wim*_*wim 236 python math floating-point hash pi
Python中无穷大的哈希值具有与pi匹配的数字:
>>> inf = float('inf')
>>> hash(inf)
314159
>>> int(math.pi*1e5)
314159
Run Code Online (Sandbox Code Playgroud)
这仅仅是巧合还是故意的?
Shr*_*saR 214
简介:这不是巧合;在Python的默认CPython实现中_PyHASH_INF被硬编码为314159,并在2000年由Tim Peters选为任意值(显然是?的数字)。
的值hash(float('inf'))是数值类型内置散列函数的系统相关的参数中的一个,并且也可以作为sys.hash_info.inf在Python 3:
>>> import sys
>>> sys.hash_info
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003, algorithm='siphash24', hash_bits=64, seed_bits=128, cutoff=0)
>>> sys.hash_info.inf
314159
Run Code Online (Sandbox Code Playgroud)
(与PyPy的结果相同。)
就代码而言,hash是一个内置函数。在Python float对象上调用它会调用函数,该函数的指针由内置float类型()的tp_hash属性给定,该类型是定义为的函数,该函数又具有PyTypeObject PyFloat_Typefloat_hashreturn _Py_HashDouble(v->ob_fval)
>>> import sys
>>> sys.hash_info
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003, algorithm='siphash24', hash_bits=64, seed_bits=128, cutoff=0)
>>> sys.hash_info.inf
314159
Run Code Online (Sandbox Code Playgroud)
其中_PyHASH_INF被定义为 314159:
if (Py_IS_INFINITY(v))
return v > 0 ? _PyHASH_INF : -_PyHASH_INF;
Run Code Online (Sandbox Code Playgroud)
从历史的角度来看,Tim Peters于2000年8月添加了314159在Python代码中(使用git bisect或可以找到git log -S 314159 -p)在此上下文中的第一次提及,现在在git存储库中提交了39dce293。cpython
提交消息说:
修复了http://sourceforge.net/bugs/?func=detailbug&bug_id=111866&group_id=5470的问题。这是一个令人误解的错误-真正的“错误”是
hash(x)当xinfinity为无限时返回错误。固定的。向添加了新的Py_IS_INFINITY宏pyport.h。重新排列了代码以减少浮点数和复数的散列中不断增长的重复,从而将Trent之前的尝试推到了合理的结论。修复了一个极为罕见的错误,即即使没有错误,浮点数的哈希也可能返回-1(并没有浪费时间来构造一个测试用例,从代码中很明显地知道它可能发生)。改进了复杂的哈希,因此hash(complex(x, y))不再系统地相等hash(complex(y, x))。
特别是,在此提交中,他撕掉了static long float_hash(PyFloatObject *v)in 的代码Objects/floatobject.c并使它成为just return _Py_HashDouble(v->ob_fval);,并在in的定义long _Py_HashDouble(double v)中Objects/object.c添加了以下几行:
#define _PyHASH_INF 314159
Run Code Online (Sandbox Code Playgroud)
因此,如上所述,这是一个任意选择。请注意,271828由e的前几个十进制数字形成。
相关的以后的提交:
由Mark Dickinson在2010年4月发布(也是),使Decimal类型的行为类似
由Mark Dickinson在2010年4月(同样)将检查移至顶部并添加了测试用例
由Mark Dickinson公司在2010年5月的问题8188,完全重写哈希函数的当前实现,但保留这个特殊的情况下,给定一个名称_PyHASH_INF(也取出271828这就是为什么在Python 3倍hash(float('-inf'))的回报-314159,而不是-271828因为它在Python 2)
作者:Raymond Hettinger,2011年1月,在Python 3.2的“新功能”中添加了一个sys.hash_info显示上述值的明确示例。(请参阅此处。)
作者Stefan Krah在2012年3月修改了Decimal模块,但保留了该哈希值。
由基督教海梅斯在2013年11月,移动的定义_PyHASH_INF来自Include/pyport.h于Include/pyhash.h它现在的生活。
Pat*_*ugh 45
我找不到关于此的任何讨论,也没有提供原因的评论。我认为它或多或少是任意选择的。我想只要它们不为其他散列使用相同的有意义的值,就没有关系。
Ale*_*ine 11
确实,
sys.hash_info.inf
Run Code Online (Sandbox Code Playgroud)
返回314159。该值不会生成,而是内置在源代码中。事实上,
hash(float('-inf'))
Run Code Online (Sandbox Code Playgroud)
-271828在python 2中返回或大约为-e(现在为-314159)。
将所有时间中两个最著名的无理数用作哈希值的事实使得它不太可能是巧合。
| 归档时间: |
|
| 查看次数: |
26497 次 |
| 最近记录: |