Расчет хеш-кода, зачем умножать и игнорировать биты переполнения?

Этот вопрос не о том, почему умножают, это довольно очевидно - он о распределении.

Зачем использовать простое число в хэш-коде?

Но скорее, это больше касается одного свойства умножения, которое становится более важным, чем больше факторов включается в формулу вычисления хэш-кода.

Простое вычисление, очевидно, может выходить за рамки, но это не имеет большого значения.

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 битами, то значение было бы другим.

7
задан Community 23 May 2017 в 11:55
поделиться