Python 中的 inf 的 hash 值和 π 有一样的数值
>>> inf = float(‘inf’)
>>> hash(inf)
314159
这个 hash 值看着眼熟,不就是 π (约为 3.1415926)的前面几位嘛。
而在 Python 3 中,这个 hash 值位于系统信息中
>>> import sys
>>> sys.hash_info.inf
314159
那么,无限大 inf 和圆周率有什么关系呢?
思考的分割线
答案是,(大概)并没有什么关系。只是恰好默认的 CPython 的实现中硬编码了这个数字而已。
#define _PyHASH_INF 314159
#define _PyHASH_NAN 0
这个数字最早是由 Tim Peters (发明了排序算法 Timsort, 也是 Python 的主要贡献者之一)在 2000 年 8 月递交的, 对应的 commit 是:
https://github.com/python/cpython/commit/39dce29365d287dc6b353b2a527dc11fe58dcfa6
感兴趣的可以去看看。在这个递交中,有一处修改是:
if (Py_IS_INFINITY(intpart))
/* can’t convert to long int — arbitrary */
v = v < 0 ? -271828.0 : 314159.0;
注意其中除了 inf 的 hash 值, -inf 的 hash 值也是从这时定下来的:271828, 而这个数字看上去和 π 并没有什么关系。
>>> hash(float(‘-inf’))
-271828
等等!这个数字看上去也有点眼熟,这不就是 e (自然对数的底,约为 2.7182818)的前面几位嘛。
那么,回到原来的问题,inf 的 hash 值,和 π 有什么关系呢?虽然没有数学或逻辑上的关系,但是从 -inf 的 hash 值的选择上看,作者显然是从 π / e 这两个数中抽取的。
“阅读原文”指向 GitHub 上 CPython 的对应源码文件。