Этот вопрос не о том, почему умножают, это довольно очевидно - он о распределении.
Зачем использовать простое число в хэш-коде?
Но скорее, это больше касается одного свойства умножения, которое становится более важным, чем больше факторов включается в формулу вычисления хэш-кода.
Простое вычисление, очевидно, может выходить за рамки, но это не имеет большого значения.
a * 31 + b
Настоящая проблема проявляется, когда много элементы находятся в формуле.
((a * 31) + b) * 31 ... 6n.
После включения более 5 или 6 членов значение первого члена теряется, поскольку его биты имеют переполнение к тому времени, когда значение хэш-кода достигает значения 5+. При использовании этой системы только последние 5 или около того членов действительно вносят значительный вклад в окончательное значение.
31 ^ 7 > Integer.MAX_VALUE
Так почему бы в большинстве вычислений не перевернуть биты, которые переполняются, и выполнить xor с младшими битами результата. Я понимаю, что это требует немного возиться с битами, и вычисления должны выполняться с использованием длинных (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 на 17x, то младшие биты были бы идентичны. Однако, если бы самые верхние биты не были «потеряны» из-за переполнения и xord с младшими 32 битами, то значение было бы другим.