web-dev-qa-db-fra.com

Nombre magique en boost :: hash_combine

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?

84
Fred Foo

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.

126
Mike Seymour

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.

23
NPE