2012-01-27 10 views
7

Podczas przeglądania wdrożenie generycznego Dictionary<TKey, TValue> klasy w pliku mscorlib.dll, zauważyłem następujące używane wiele razy, aby uzyskać hash-klucz:GetHashCode (key) i int.MaxValue

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

GetHashCode() zwraca int. Czy jestem w błędzie myśląc, że bitowe ORAZ pomiędzy int.MaxValue i dowolną liczbą całkowitą x, zawsze zwróci x?

Czy ktoś może wyjaśnić, dlaczego operator & jest używany w powyższy sposób?

Odpowiedz

10

Wartość int.MaxValue jest 0x7FFFFFFF - najbardziej znaczącym bitem jest zero. Stąd, gdy wykonujesz bitowe i inne int, efektywnie wyzerujesz bit "znaku". Zauważ, że z powodu zastosowanego kodowania two's complement, -1 nie stanie się 1, ale raczej 2147483647.

Wygląda na to, że z jakiegoś powodu w zmiennej kodowej num dozwolone są tylko liczby całkowite dodatnie.

+3

Najbardziej prawdopodobną przyczyną tego jest obliczenie wartości wyniku modulo liczby wiader, aby uzyskać prawidłową łyżkę. To nie działa poprawnie dla liczb ujemnych. – svick

+0

Byłbym skłonny postawić cały dolar, że implementacja słownika w .NET nie obchodzi, czy hashcode jest pozytywne czy negatywne, i że osoba, która napisała kod, robi to w (prawdopodobnie nieuprawnionej) próbie aby uniknąć dopasowania współczynników prime z liczbą segmentów: http://stackoverflow.com/questions/3613102/why-use-a-prime-number-in-hashcode –

+0

@Chris: Według PO, ten kod * jest * z implementacji .NET 'Dictionary '. Jak sugeruje svick, prawdopodobnie zapewnia to, że numer wiadra - indeks tablicy, iirc - jest zawsze dodatni. – LukeH

1

nie wpłynie dodatnimi liczbami

  • [0 int.MaxValue] -> pozostaje niezmieniona
  • [int.MinValue -1] -> zmieni bit znaku
+0

Druga instrukcja jest niepoprawna. 'int.MinValue & int.MaxValue == 0'. Wartości ujemne zostaną zwrócone jako (wartość + 2147481498). –

+0

'int.MinValue & int.MaxValue == 0' ... ale to właśnie zmienia nieco znak, myślę, że to prawda. W każdym razie Ondrej zapewnił lepsze wyjaśnienie. – doblak