這個問題不是關於爲什麼一個乘法,這是相當明顯的 - 它的分佈。哈希碼計算爲什麼要乘和忽略溢出位?
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