Perché '397' viene utilizzato per l'override GetSashCode di ReSharper?


150

Come molti di voi, utilizzo ReSharper per accelerare il processo di sviluppo. Quando lo usi per sovrascrivere i membri di uguaglianza di una classe, il code-gen che produce per GetHashCode () appare come:

    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;
        }
    }

Ovviamente ho alcuni dei miei membri lì dentro, ma quello che voglio sapere è perché 397?

  • EDIT: Quindi la mia domanda sarebbe meglio formulata in quanto, c'è qualcosa di "speciale" nel fatto che il numero primo 397 al di fuori di esso è un numero primo?

Risposte:


166

Probabilmente perché 397 è un numero primo di dimensioni sufficienti per causare l'overflow della variabile risultante e mescolare in qualche modo i bit dell'hash, fornendo una migliore distribuzione dei codici hash. Non c'è nulla di particolarmente speciale nel 397 che lo distingue dagli altri numeri primi della stessa grandezza.


73
E 397 è felice. Non vogliamo solo essere felici?
Russell B,

2
Va bene, ma perché deve essere primo, e perché deve avere la stessa grandezza? Se deve essere primo, perché non 2 o 2147483647? Immagino di ottenere una mutazione piacevole (e l'unica ragione di questa moltiplicazione è la mutazione) non abbiamo bisogno del numero per essere primi. Abbiamo bisogno che il moltiplicatore abbia relativamente lo stesso numero o zero e uno, preferibilmente senza schemi espliciti. 397 = 110001101b conforme. Non sono ancora sicuro della grandezza.
Andriy K,

5
Come ha detto Nick, non c'è niente di particolarmente speciale. Non è NECESSARIO avere quella dimensione, questo è solo un numero abbastanza grande che quando si calcola un hash il risultato traboccerà (poiché GetHashCode () restituisce un Int32). La selezione di un numero primo è solo utile per la distribuzione, non ho una laurea in matematica, quindi non proverò a spiegarlo, ma la moltiplicazione per un numero primo avrà un risultato che è più ben distribuito della moltiplicazione per qualsiasi altro numero arbitrario.
Ben Randall,

16

L'hash utilizzato dal resharper sembra una variante dell'hash FNV . FNV è spesso implementato con numeri primi diversi. C'è una discussione sulla scelta appropriata di numeri primi per FNV qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.