c++ - 有趣的 stdext::hash_value() 实现

标签 c++ visual-studio-2010 hash c++11

我在 VS2010 上使用 stdext::hash_value() 尝试了一些哈希算法并意识到了这一点:

#include <iostream>
#include <xhash>
using namespace std;

int main() 
{
#ifdef _WIN64
    std::cout << "x64" << std::endl;
#else
    std::cout << "x32" << std::endl;
#endif

    std::cout << stdext::hash_value(345.34533) << std::endl;
    std::cout << stdext::hash_value(345.566) << std::endl;

    return 0;
}

// Output is:
// x64
//3735928758
//3735928758

我尝试了其他一些具有相同整数但小数部分不同的 double 变量。比如 1.234 对 1.568。哈希值始终相同。所以我查看了 hash_value() 的源代码并看到了

#define _HASH_SEED  (size_t)0xdeadbeef

template<class _Kty> inline
size_t hash_value(const _Kty& _Keyval)
{   // hash _Keyval to size_t value one-to-one
    return ((size_t)_Keyval ^ _HASH_SEED);
}

_KeyVal 被转换为 size_t 这对我来说没有意义。该函数只是忽略了 double 的小数部分。这个实现背后的逻辑是什么?是错误还是功能?

最佳答案

stdext::hash_value 不是哈希函数。它是散列函数的输入,您可以根据您的类型对其进行专门化,以便它可以用作 stdext 散列类的键。但是似乎没有任何文档。实际的散列函数是 stdext::hash_compare。

但是因为没有 hash_value 的默认特化,所以它使用忽略小数部分的转换为 int 的方法。

在 vc10 之前,标准 std::tr1::hash/std::hash 函数存在几乎相同的错误:

http://connect.microsoft.com/VisualStudio/feedback/details/361851/std-tr1-hash-float-or-hash-double-is-poorly-implemented

在 vc10 中,std::hash 获得了对位进行散列的双重特化。我想 stdext 现在被认为已经过时了,所以即使在 vc10 中也没有修复它。

关于c++ - 有趣的 stdext::hash_value() 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5516365/

相关文章:

.net - 如何在 Visual Studio (.net) 开发的程序中从 SQL 数据库返回特定字段

mysql - 在 MySQL 中存储散列密码

AJAX 登录调用中的 Javascript 散列,更安全?

c++ - 这个元素在 c++ Qt 中被称为什么?

c++ - boost::multi_array View 和子数组之间有什么区别

c++ - 如何正确使用结构数组?

json - 向引用了 JSON.NET 库的项目添加服务引用时出现奇怪的问题

c++ - 由于某种原因,我的 ram 上的 int 重量超过 32 位

ruby - 在 Ruby 中,如何从具有值的哈希中提取键

c++ - lcov 报告未执行静态成员变量析构函数中的行