前言
某天看着github上开源引擎的写法中,有个神奇一样的数字0x9e3779b9
,很是诧异,于是又是经典的google
、stkof
、stkExchange
三个地方找解释,于是有了这篇记录
正文
在处理哈希表的代码中,我经常发现常量 0x9e3779b9 或者有时是 0x9e3779b1。例如
hash = n * 0x9e3779b1 >>> 24
phi = (1 + sqrt(5)) / 2
2^32 / phi = 0x9e3779b9
来自stkof的解答
0x9e3779b9 是黄金比例的小数部分 0.61803398875…(sqrt(5)-1)/2 的整数部分,乘以 2^32。
因此,如果 φ = (sqrt(5)+1)/2 = 1.61803398875 是黄金比例,哈希函数计算 n * φ 的小数部分,它具有很好的散射特性。为了说服自己,只需(n, n*c-FLOOR(n*c))在您最喜欢的电子表格中创建一个散点图,替换c为 φ、e、π 等。https://lkml.org/lkml/2016/中描述了一些在弄错时的有趣现实问题838 年 4 月 29 日。
这种方法通常被称为“黄金比率散列”或“斐波那契散列”,由 Donald Knuth 推广(计算机编程艺术:第 3 卷:排序和搜索)。在数量理论方面,它主要归结为 Steinhaus 猜想 ( https://en.wikipedia.org/wiki/Three-gap_theorem ) 和黄金比例 φ 倍数的小数部分的递归对称性。
有时,您可能还会看到0x9e3779b1,这是最接近的素数0x9e3779b9(并且似乎有点“货物崇拜”,因为这不是模块化哈希)。类似地,0x9e3779b97f4a7c15和0x9e3779b97f4a7c55是这些数字的 64 位等价物。
使用类似的"Magic number"时,注释中带上来源会更好一些
# Golden Ratio constant used for better hash scattering
# See https://softwareengineering.stackexchange.com/a/402543
GOLDEN_RATIO = 0x9e3779b1
hash = n * GOLDEN_RATIO