这个问题不是关于为什么一个乘法,这是相当明显的 - 它的分布。哈希码计算为什么要乘和忽略溢出位?
Why use a prime number in hashCode?
而恰恰这是成为更多的因素包括在散列码计算公式更重要乘法更多关于一个性质。
一个简单的计算显然可能会溢出,但这并不重要。
a * 31 + b
真正的问题是当许多项目在公式中被证明。
((a * 31) + b) * 31 ... 6n.
一旦超过5或6项是包括作为其位由哈希码值是至多包括5+术语时有溢出的第一项的值被丢失。使用这个系统只有最后5个左右的术语才是最终价值的重要贡献者。
31^7 > Integer.MAX_VALUE
那么,为什么大多数计算没有回滚周围的溢出位,并且xor w /结果的低位。我赞赏这需要一些小窍门,并且计算必须使用长整数(64位)来完成,所以前32位可以与整数结果进行XOR运算,但至少不会丢失任何位。
溢出被忽略的原因是什么?如前所述,使用长时间并不昂贵。
EDIT
100000*31^7= 2751261411100000 0x9C641F717C560
6553600000*31^7 180306667837849600000 0xC641F717C5600000
注意,后者的值比以前更大的准确65536倍这也意味着它的答案是16位大。请注意,整数值 0xC641F717C5600000是0xC5600000实际有效值从16位值丢失。
*SAMPLE A*
65536*4096*27512614111
=7385361114638319616
=0x667E12CDF0000000
12345678
=0xF0000000
*SAMPLE B*
9*65536*4096*27512614111
=66468250031744876544
=0x9A6EA93D70000000
12345678
=0x70000000
注意样品B的最顶部位这正是9X 样品A使得在最后的32位的值几乎绝对没有差异 - 如果我改变9X到17倍,然后较低位将是相同。但是,如果由于溢出而导致最高位未被“丢失”并且低32位的xord值则会不同。
不仅如此,而且很长一段时间会遇到同样的问题,只会花费一点点时间。 (对不起,这是一个糟糕的...) – corsiKa 2011-02-10 08:22:08
素数作为乘数的全部原因是因为可能性意味着数值向左移动,最终所有位都丢失。然而,素数仍然有相同的概率,他们会更好一点,需要更长的时间消失。 – 2011-02-11 12:03:06