Nombre magique dans boost::hash_combine
La boost::hash_combine
fonction de modèle prend une référence à un hachage (appelé seed
) et un objet v
. Selon le docs, il combine seed
avec le hash de v
par
seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
Je vois que c'est déterministe. Je ne vois pourquoi un XOR est utilisé.
Je parie que les plus aide à la cartographie des valeurs similaires largement séparées, afin de sonder les tables de hachage ne se décomposent pas, mais quelqu'un peut m'expliquer ce que la magie de la constante est?
- Étant donné que sur de nombreux ordinateurs un entier tourner coûtent environ le même prix qu'un changement aurait-il un quelconque avantage dans la conversion de l'expression: <code> la graine ^= hash_value(v) + 0x9e3779b9 + rotl(semences, 6) + rotr(semences, 2); </code>
Vous devez vous connecter pour publier un commentaire.
Le nombre magique est censé être 32 bits aléatoires, où chacun est tout aussi susceptibles d'être égal à 0 ou 1, et avec pas de corrélation simple entre les bits. Une façon courante de trouver une chaîne de tels morceaux est d'utiliser le binaire de l'expansion d'un nombre irrationnel; dans ce cas, ce nombre est l'inverse du nombre d'or:
Donc y compris ce nombre de façon "aléatoire" des changements de chaque bit de la semence; comme vous le dites, cela signifie que les valeurs consécutives seront éloignés. Y compris la nouvelle versions de la semence vieille de permet de s'assurer que, même si
hash_value()
a une assez petite plage de valeurs, les différences vont bientôt se propager à travers tous les bits.sizeof(size_t)
?python -c "import math; print hex(int(2**64 / (1 + math.sqrt(5)) / 2))"
produit0x278dde6e5fd29e00
pour moi. J'attends qui fonctionne assez bien pour quand size_t est 64-bits.0x9e3779b97f4a7800
0x9e3779b97f4a7c15
.0x9e3779b97f4a7c16
? Je veux dire, il est à seulement 1 arrêt.0xFFFFFFFFFFFFFFFF
parphi
et pas2^64
.long double
à la place.long double
seulement a 64 bits de précision, il n'est pas tout à fait assez pour le calcul ici.1/2
est exactement0.5
dans cet univers, à proprement parler.sizeof(long double)
de 10 octets (80 bits) sur coliru (x87 long double) et de 16 octets (128 bits) sur GCC x86-64.Prendre un coup d'oeil à la DDJ article de Bob Jenkins depuis 1997. La magie de la constante ("nombre d'or") est expliquée comme suit: