为什么“ 397”用于ReSharper GetHashCode覆盖?


150

像你们中的许多人一样,我使用ReSharper来加快开发过程。当您使用它覆盖类的相等性成员时,它为GetHashCode()生成的代码源如下:

    public override int GetHashCode()
    {
        unchecked
        {
            int result = (Key != null ? Key.GetHashCode() : 0);
            result = (result * 397) ^ (EditableProperty != null ? EditableProperty.GetHashCode() : 0);
            result = (result * 397) ^ ObjectId;
            return result;
        }
    }

当然,我那里有一些我自己的成员,但是我想知道为什么是397?

  • 编辑:所以我的问题最好用这样的措辞,因为除了397质数以外,是否还有一些“特殊”的质数?

Answers:


165

可能是因为397是一个足够大的素数,导致结果变量溢出并在某种程度上混合了哈希的位,从而提供了更好的哈希码分布。397并没有什么特别之处可以将其与相同大小的其他素数区分开。


73
397很高兴。我们不是都想开心吗?
罗素B

2
好的,但是为什么它必须是最主要的,为什么它必须具有如此精确的大小?如果必须是素数,为什么不选择2或2147483647?我猜想得到很好的突变(并且唯一的原因就是突变),我们不需要数字是素数。我们需要乘数具有相对相同的数字或零和一,最好没有显式模式。397 = 110001101b符合。仍然不确定幅度。
Andriy K

5
正如尼克所说,这没有什么特别的。不需要那个大小,这只是一个足够大的数字,以至于当您计算哈希时,结果将溢出(因为GetHashCode()返回Int32)。选择素数只是对分布有帮助,我没有数学学位,所以我不会尝试解释它,但是与素数相乘比与任何其他任意数相乘的结果分布更好。
本·兰德尔

16

重新共享程序使用的哈希看起来像FNV哈希的变体。FNV通常以不同的素数实现。有一个关于素数FNV选用合适的讨论在这里

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.