关于整数乘法,溢出和信息丢失

Bil*_*ard 14 java overflow hashcode multiplication

我正在阅读Joshua Bloch的Effective Java 第3章.在第8项:覆盖equals时始终覆盖hashCode,作者在其散列函数中使用以下组合步骤:

result = 37 * result + c;
Run Code Online (Sandbox Code Playgroud)

然后他解释了为什么选择了37(强调添加):

选择乘法器37是因为它是奇数素数.如果它是偶数并且乘法溢出,则信息将丢失,因为乘以2相当于移位.使用素数的优点不太清楚,但为此目的使用素数是传统的.

我的问题是为什么组合因子(37)是奇数是重要的?不管乘数是奇数还是偶数,乘法溢出都不会导致信息丢失?

And*_*mas 15

考虑当一个正值在一个base-2表示中重复乘以2时会发生什么 - 所有的设置位最终都会从结尾开始,让你为零.

偶数乘数将导致具有较少多样性的哈希码.

另一方面,奇数可能会导致溢出,但不会损失多样性.

  • 即使在您完全归零结果之前,问题也会出现.考虑将8位散列乘以2的乘数一次 - 它以256个可能的值开始,并以128个可能的值结束. (3认同)