156 votes

Pourquoi la valeur '397' est-elle utilisée pour le remplacement de ReSharper GetHashCode ?

Comme beaucoup d'entre vous, j'utilise ReSharper pour accélérer le processus de développement. Lorsque vous l'utilisez pour surcharger les membres d'égalité d'une classe, le code-générique qu'il produit pour la classe GetHashCode() ressemble :

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

Bien sûr, j'y ai inclus certains de mes propres membres, mais ce que je veux savoir, c'est pourquoi 397 ?

  • EDIT : Ma question serait donc mieux formulée comme suit : le nombre premier 397 a-t-il quelque chose de "spécial" en dehors du fait qu'il s'agit d'un nombre premier ?

173voto

Nick Johnson Points 79909

Probablement parce que 397 est un nombre premier de taille suffisante pour faire déborder la variable de résultat et mélanger quelque peu les bits du hachage, ce qui permet une meilleure distribution des codes de hachage. Il n'y a rien de particulièrement spécial à propos de 397 qui le distingue des autres nombres premiers de la même magnitude.

77 votes

Et 397 est heureux. Ne voulons-nous pas tous être heureux ?

2 votes

D'accord, mais pourquoi faut-il qu'elle soit première, et pourquoi faut-il qu'elle soit de cette magnitude exacte ? S'il doit être premier, pourquoi pas 2 ou 2147483647 ? Je suppose que pour obtenir une belle mutation (et la seule raison de cette multiplication est la mutation), il n'est pas nécessaire que le nombre soit premier. Nous avons besoin que le multiplicateur ait relativement le même nombre ou des zéros et des uns, de préférence sans modèle explicite. 397=110001101b est conforme. Je ne suis toujours pas sûr de la magnitude.

5 votes

Comme Nick l'a dit, il n'y a rien de particulièrement spécial. Il n'est pas nécessaire qu'il soit de cette taille, c'est juste un nombre suffisamment grand pour que le résultat déborde lorsque vous calculez un hash (puisque GetHashCode() renvoie un Int32). La sélection d'un nombre premier est juste utile pour la distribution, je n'ai pas de diplôme de mathématiques donc je ne vais pas essayer de l'expliquer, mais la multiplication par un nombre premier aura un résultat plus bien distribué que la multiplication par n'importe quel autre nombre arbitraire.

18voto

Nick Craver Points 313913

Ben a raison, en reflétant l'Assemblée, vous pouvez voir que c'est juste un nombre premier qu'ils ont choisi d'utiliser.

18voto

kybernetikos Points 3127

Le hachage utilisé par resharper ressemble à une variante de l'option FNV hachage. Le FNV est fréquemment mis en œuvre avec des nombres premiers différents. Il y a une discussion sur le choix approprié des nombres premiers pour FNV. aquí .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X