Python中无穷大的哈希具有与pi相匹配的数字:
>>> inf = float('inf')
>>> hash(inf)
314159
>>> int(math.pi*1e5)
314159
这仅仅是巧合还是故意的?
答案 0 :(得分:201)
摘要:这不是巧合; _PyHASH_INF
is hardcoded as 314159在Python的默认CPython实现中,并且被选为任意值(显然是从π的数字开始)by Tim Peters in 2000。
hash(float('inf'))
的值是数字类型的内置哈希函数的系统相关参数之一,而is also available在Python 3中则为sys.hash_info.inf
。
>>> 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
(结果也with PyPy也一样。)
就代码而言,hash
是一个内置函数。在Python浮点对象上调用它会调用函数,该函数的指针由内置浮点类型(PyTypeObject PyFloat_Type
)的tp_hash
attribute给定,其中is是float_hash
函数, defined为return _Py_HashDouble(v->ob_fval)
,而has
if (Py_IS_INFINITY(v))
return v > 0 ? _PyHASH_INF : -_PyHASH_INF;
其中_PyHASH_INF
是defined as 314159:
#define _PyHASH_INF 314159
从历史的角度来看,Tim Peters添加了在此上下文中Python代码(您可以使用314159
或git bisect
找到的git log -S 314159 -p
的第一次提及)在2000年8月,现在在cpython
git存储库中提交了39dce293。
提交消息显示:
修复http://sourceforge.net/bugs/?func=detailbug&bug_id=111866&group_id=5470。 这是一个误导性错误-真正的“错误”是
hash(x)
给出了一个错误 当x
为无穷大时返回。固定的。向其中添加了新的Py_IS_INFINITY
宏pyport.h
。重新排列代码以减少float和 复数,使Trent早些时候的努力达到了合理的结论。 修复了极其罕见的错误,即即使存在浮点数的哈希也可能返回-1 这不是一个错误(没有浪费时间来构造一个测试用例,这仅仅是 从代码中可以很明显地看出来)。改进了复杂的哈希,以便hash(complex(x, y))
不再系统地等于hash(complex(y, x))
。
尤其是,在此提交中,他摘录了static long float_hash(PyFloatObject *v)
中Objects/floatobject.c
的代码,使其仅为return _Py_HashDouble(v->ob_fval);
,以及{{1 }}他添加了以下几行:
long _Py_HashDouble(double v)
因此,如上所述,这是一个任意选择。请注意,271828由e的前十进制数字组成。
相关的以后提交:
By Mark Dickinson in Apr 2010(also),使Objects/object.c
类型的行为类似
By Mark Dickinson in Apr 2010(also),将此检查移到顶部并添加测试用例
By Mark Dickinson in May 2010为issue 8188,将哈希函数完全重写为its current implementation,但保留了这种特殊情况,为常量命名为 if (Py_IS_INFINITY(intpart))
/* can't convert to long int -- arbitrary */
v = v < 0 ? -271828.0 : 314159.0;
(也删除了271828,这就是为什么在Python 3中Decimal
返回_PyHASH_INF
而不是在Python 2中返回hash(float('-inf'))
的原因)
By Raymond Hettinger in Jan 2011,在-314159
的Python 3.2的“新功能”中添加了一个明确的示例,显示了上述值。 (请参见here。)
By Stefan Krah in Mar 2012修改Decimal模块,但保留此哈希。
By Christian Heimes in Nov 2013,将-271828
的定义从sys.hash_info
移到了现在居住的_PyHASH_INF
。
答案 1 :(得分:32)
_PyHASH_INF
等于314159
的{{3}}。
我找不到关于此的任何讨论或提供原因的评论。我认为它或多或少是任意选择的。我想只要它们不将相同的有意义的值用于其他哈希,就没关系。
答案 2 :(得分:10)
确实
function findeventlog {
# Get current month = eg. May
# Find all files earlier than [get current month]
# List all files that have last write time in the past.
# Get-Date returns a DateTime that contains methods for addition
$files = Get-Childitem -path c:\path\to\logs | ` # ` is used here for wrapping
Where-Object { $_.LastWriteTime -le (get-date).AddMonths(-1) }
# define exclusion list of zip files = "*.zip"
# Files collection can be filtered. ? is shorthand for where-object
# For a list of all properties, refer to docs.microsoft.com or use Get-Member
$files = $files | ? { $_.someProperty -ne something }
# define event log folder = Drive\eventlogbackup\eventlogs
# define zip destination folder = F:\eventlogbackup\eventlog -filter -recurse
# define zips to create = find items in event log folder and exclude (list)
# define zips to create.count
# zip (define zips to create)
Compress-Archive -LiteralPath $files -Destination c:\my\archive\location
}
返回sys.hash_info.inf
。该值不会生成,而是内置在源代码中。
实际上,
314159
在python 2(it's -314159 now)中返回hash(float('-inf'))
或大约为-e。
使用所有时间中两个最著名的无理数作为哈希值的事实使得它不太可能是巧合。