Dot-Net
.Net GetHashcode 移位操作
昨天我瀏覽了一些 .net 原始碼,看到了 GetHashcode 的幾個實現,其中包含以下內容:
(i1 << 5) + i ^ i2我了解程式碼在做什麼以及為什麼。我想知道的是為什麼他們使用 (i1 << 5) + i 而不是 (i1 << 5) - i。
我見過的大多數框架都使用 -i 因為這相當於乘以 31,這是素數,但微軟的方式相當於乘以 33,它有 11 和 3 作為因數,因此不是素數。
這有什麼已知的理由嗎?有什麼合理的假設嗎?
我在 math.stackexchange.com 上問了同樣的問題:Curious Properties of 33。
數學家的猜想和我對這個話題所做的研究讓我相信答案是這樣的:
好的,我知道了為什麼微軟使用 33。這就是 Bernstein Hash。事實證明,33 具有一些神奇的特性,可以產生良好的雜湊碼分佈,而關於原因的理論知識很少。
基本上,在熵和速度比較中,伯恩斯坦做得足夠好,而且相當敏捷。提出常數 33 的 Dan Bernstein 無法解釋 33 的什麼屬性產生瞭如此好的散列分佈。
已經寫了幾篇比較散列函式的論文,並且在沒有進一步解釋使用 33 的好處的情況下證實了這一發現。此外,我找不到 Java 使用 31 的原因。迄今為止,這似乎是一個數學和程式之謎。