2012-01-27 18 views
7

Mientras navega por la implementación de la clase genérica Dictionary<TKey, TValue> en mscorlib.dll, me di cuenta de las siguientes muchas veces utilizadas para obtener un hash de clave: GetHashCodeGetHashCode (llave) y int.MaxValue

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

() regresa un int. ¿Me equivoco al pensar que un AND a nivel de bits entre int.MaxValue y cualquier número entero x, siempre devolverá x?

¿Alguien puede explicar por qué el operador & se utiliza de la manera anterior?

Respuesta

10

El valor de int.MaxValue es 0x7FFFFFFF - el bit más significativo es cero. Por lo tanto, cuando realiza un bitwise y con otro int, efectivamente pone a cero el bit 'sign'. Tenga en cuenta que debido a la codificación two's complement utilizada, -1 no se convertirá en 1, sino en 2,147,483,647.

Aparentemente, por algún motivo solo se permiten enteros positivos en la variable num en la muestra del código.

+3

La razón más probable para hacer esto es que se calculará el valor del número de módulo de resultado de cubos para obtener el depósito correcto. Eso no funcionaría bien para números negativos. – svick

+0

Estaría dispuesto a apostar todo un dólar que a la implementación del Diccionario en .NET no le importa si el código es positivo o negativo, y que la persona que escribió el código lo está haciendo en un intento (probablemente desacertado) para tratar de evitar la coincidencia de factores primos con el número de segmentos: http://stackoverflow.com/questions/3613102/why-use-a-prime-number-in-hashcode –

+0

@Chris: según el OP, ese código * es * de la implementación .NET 'Dictionary '. Como lo sugiere svick, es probable que se asegure de que el número de segmento (un índice de matriz, iirc) siempre sea positivo. – LukeH

1

No afectará números positivos

  • [0, int.MaxValue] -> permanece sin cambios
  • [int.MinValue, -1] -> alterará el bit de signo
+0

La segunda declaración es incorrecta. 'int.MinValue & int.MaxValue == 0'. Los valores negativos se devolverán como (valor + 2147481498). –

+0

'int.MinValue & int.MaxValue == 0' ... pero eso está alterando exactamente el bit de signo, supongo que es correcto. De todos modos, Ondrej brindó una mejor explicación. – doblak