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