GetHashCode(key) & int.MaxValue

8

在浏览mscorlib.dll中通用的Dictionary<TKey, TValue>类的实现时,我注意到以下内容被多次用于获取哈希键:

int num = this.comparer.GetHashCode(key) & int.MaxValue;

GetHashCode()返回一个整数。我是否错误地认为int.MaxValue与任何整数x之间的按位与操作将始终返回x

有人能解释一下为什么要以上述方式使用&运算符吗?

2个回答

11

int.MaxValue 的值为 0x7FFFFFFF — 最高位为零。因此,当你对另一个 int 值进行位与操作时,实际上是将“符号”位清零。请注意,由于采用了二进制补码编码,-1 不会变成 1,而是变成 2,147,483,647。

显然,在您的代码示例中,num 变量只允许使用正整数。


4
这么做的最可能原因是计算结果模桶数的值,以获得正确的桶。这对负数不起作用。 - svick
我敢打赌,.NET中的字典实现不在乎哈希码是正数还是负数,并且编写代码的人正在尝试(可能是不明智的)避免将质因数分解与桶的数量匹配。https://dev59.com/y3A65IYBdhLWcg3w1SNC - Chris Shain
@Chris:根据OP的说法,该代码确实来自.NET Dictionary<K,V> 实现。正如svick所建议的那样,这可能是为了确保桶号(一个数组索引,如果我没记错的话)始终为正数。 - LukeH
@LukeH 你说得完全正确,我完全误读了问题。 - Chris Shain

2

这不会影响正数

  • [0,int.MaxValue] --> 不变
  • [int.MinValue,-1] --> 会改变符号位

第二个语句是不正确的。int.MinValue&int.MaxValue == 0。负值将返回为(value + 2147481498)。 - Hand-E-Food
int.MinValue & int.MaxValue == 0 ... 但这实际上是改变了符号位,我想这是正确的。无论如何,Ondrej 提供了更好的解释。 - doblak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接