我在 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 函数存在几乎相同的错误:
在 vc10 中,std::hash 获得了对位进行散列的双重特化。我想 stdext 现在被认为已经过时了,所以即使在 vc10 中也没有修复它。
关于c++ - 有趣的 stdext::hash_value() 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5516365/