Le boost::hash_combine
la fonction modèle prend une référence à un hachage (appelé seed
) et à un objet v
. Selon le docs , il combine seed
avec le hachage de v
par
seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
Je peux voir que c'est déterministe. Je vois pourquoi un XOR est utilisé.
Je parie que l'ajout aide à mapper des valeurs similaires de manière très éloignée afin que les tables de hachage ne se décomposent pas, mais quelqu'un peut-il expliquer quelle est la constante magique?
Le nombre magique est censé être 32 bits aléatoires, chacun étant également susceptible d'être égal à 0 ou 1, et sans simple corrélation entre les bits. Une manière courante de trouver une chaîne de tels bits consiste à utiliser l'expansion binaire d'un nombre irrationnel; dans ce cas, ce nombre est l'inverse du nombre d'or:
phi = (1 + sqrt(5)) / 2
2^32 / phi = 0x9e3779b9
Donc, l'inclusion de ce nombre "au hasard" change chaque bit de la graine; comme vous le dites, cela signifie que les valeurs consécutives seront très éloignées. L'inclusion des versions décalées de l'ancienne graine garantit que, même si hash_value()
a une plage de valeurs assez petite, les différences seront bientôt réparties sur tous les bits.
Jetez un œil au article DDJ de Bob Jenkins de 1997 . La constante magique ("nombre d'or") s'explique comme suit:
Le nombre d'or est vraiment une valeur arbitraire. Son but est d'éviter de mapper tous les zéros à tous les zéros.