最近,我很好奇浮点的哈希算法是如何工作的,所以我查看了boost::hash_value的源代码。原来是fairly complicated。实际实现遍历基数中的每个数字,并累积一个哈希值。与整数哈希函数相比,它涉及的内容要多得多。
我的问题是:为什么浮点散列算法应该更加复杂?为什么不直接对浮点值的二进制表示进行哈希运算,就像它是一个整数一样?
像这样:
std::size_t hash_value(float f)
{
return hash_value(*(reinterpret_cast<int*>(&f)));
}我意识到不能保证float在所有系统上都与int大小相同,但这类事情可以通过几个模板元程序来推导出一个与float大小相同的整型。那么引入一个完全不同的散列函数来专门操作浮点类型有什么好处呢?
发布于 2011-09-13 22:20:51
为什么你想要散列浮点值?出于同样的原因,比较浮点值的相等有许多陷阱,散列它们可能会产生类似的(负面)结果。
然而,考虑到您确实想要这样做,我怀疑boost算法是复杂的,因为当您考虑到非规范化数字时,不同的位模式可以表示相同的数字(并且可能具有相同的散列)。在IEEE754中,也存在比较相等但具有不同位模式的正和负0值。
如果它不会出现在你的算法中,这可能不会出现在散列中,但是你仍然需要注意信号NaN的值。
此外,散列+/- infinity和/或NaN的含义是什么?具体地说,NaN可以有许多表示,它们都应该产生相同的散列吗?Infinity似乎只有两个表示,所以它似乎可以正常工作。
发布于 2011-09-13 22:26:03
看一看https://svn.boost.org/trac/boost/ticket/4038
从本质上讲,它归结为两件事:
sizeof(float)不等于我没有发现有人提到boost散列确实避免了更少的冲突。虽然我假设从指数中分离尾数可能会有所帮助,但上面的链接并不表明这是驱动设计的决定。
发布于 2011-09-13 22:31:28
不使用位模式的一个原因是,一些不同的位模式必须被认为是相等的,因此具有相同的哈希码,即
正零值和负零值
https://stackoverflow.com/questions/7403210
复制相似问题