2012-01-27 49 views
7

在浏览在mscorlib.dll通用Dictionary<TKey, TValue>类的实现,我注意到以下使用多次获得哈希键:的GetHashCode(键)int.MaxValue

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

GetHashCode()方法返回一个int。我错误地认为int.MaxValue和任何整数之间的按位AND,将始终返回x

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

回答

10

int.MaxValue的值是0x7FFFFFFF - 最高位为零。因此,当你执行一个按位和另一个int时,你实际上将'sign'位清零。请注意,由于使用two's complement编码,-1不会变为1,而是2,147,483,647。

显然,出于某种原因,只有正整数才允许在您的代码示例中使用num变量。

+3

这样做的最可能的原因是计算桶的结果模数的值,以获得正确的桶。这对负数不适用。 – svick 2012-01-27 01:40:46

+0

我愿意赌一整美元,在.NET中Dictionary的实现并不在乎哈希码是正面还是负面,并且编写代码的人是在尝试(可能是不明智的)尝试试图避免匹配素数与桶数:http://stackoverflow.com/questions/3613102/why-use-a-prime-number-in-hashcode – 2012-01-27 01:47:29

+0

@Chris:根据OP,该代码* *来自.NET的'词典'实现。正如svick所暗示的那样,可能要确保桶号 - 数组索引iirc - 始终是正数。 – LukeH 2012-01-27 02:02:45

1

它不会影响正数

  • [0,int.MaxValue] - >保持不变
  • [int.MinValue,-1] - >将改变符号位
+0

第二种说法不正确。 'int.MinValue&int.MaxValue == 0'。负值将返回为(值+ 2147481498)。 – 2012-01-27 01:38:10

+0

'int.MinValue&int.MaxValue == 0' ...但这正是改变符号位,我想这是正确的。无论如何,Ondrej提供了一个更好的解释。 – doblak 2012-01-27 01:45:31