Магический номер в boost:: hash_combine

Функция шаблона boost::hash_combine принимает ссылку на хэш (называемый seed) и объект v. Согласно docs, он объединяет seed с хешем v от

seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);

Я вижу, что это детерминировано. Я вижу, почему используется XOR.

Я уверен, что добавление помогает в сопоставлении одинаковых значений широко, так что хэш-таблицы зондирования не будут разрушаться, но может ли кто-нибудь объяснить, что такое волшебная константа?

Ответ 1

Магическое число должно быть 32 случайных бита, где каждый одинаково вероятно равен 0 или 1, и без простой корреляции между битами. Общим способом поиска строки таких битов является использование двоичного расширения иррационального числа; в этом случае это число является обратным золотому соотношению:

phi = (1 + sqrt(5)) / 2
2^32 / phi = 0x9e3779b9

Таким образом, включение этого числа "случайно" изменяет каждый бит семени; как вы говорите, это означает, что последовательные значения будут далеко друг от друга. Включая сдвинутые версии старого семени, убедитесь, что даже если hash_value() имеет довольно небольшой диапазон значений, различия скоро будут распределены по всем битам.

Ответ 2

Взгляните на статью DDJ Боба Дженкинса с 1997 года. Магическая константа ( "золотое соотношение" ) объясняется следующим образом:

Золотое соотношение действительно является произвольным значением. Его цель - избегать отображения всех нулей во все нули.