Python hash() 不能处理长整数?
Posted
技术标签:
【中文标题】Python hash() 不能处理长整数?【英文标题】:Python hash() can't handle long integer? 【发布时间】:2011-02-10 21:12:16 【问题描述】:我定义了一个类:
A类: ''' 哈希测试类 >>> a = A(9, 1196833379, 1, 1773396906) >>> 哈希(一) -340004569 这很奇怪,预期为 12544897317L。 ''' def __init__(self, a, b, c, d): 自我.a = a 自我.b = b 自我.c = c 自我.d = d def __hash__(self): 返回 self.a * self.b + self.c * self.d为什么,在 doctest 中,hash() 函数给出一个负整数?
【问题讨论】:
【参考方案1】:它似乎仅限于 32 位。通过阅读this question,您的代码可能在 64 位机器上产生了预期的结果(使用这些特定值,因为结果适合 64 位)。
内置hash
函数的结果取决于平台并受限于本机字长。如果您需要确定性的跨平台哈希,请考虑使用hashlib
模块。
【讨论】:
【参考方案2】:见object.__hash__
注意
在 2.5 版中更改:
__hash__()
可能 现在还返回一个长整数对象; 然后导出 32 位整数 来自该对象的哈希。
在您的情况下,预期 12544897317L 是一个长整数对象,
Python 通过(12544897317 & 0xFFFFFFFF) - (1<<32)
导出32位整数-340004569
Python 通过 hash(12544897317L) 导出 32 位整数,结果为 -340004569
算法是这样的:
def s32(x):
x = x & ((1<<32)-1)
if x & (1<<31):
return x - (1<<32)
else:
return x
def hash(x):
h = 0
while x:
h += s32(x)
x >>= 32
return h
【讨论】:
Nitpick: (12544897317 & 0xFFFFFFFF) - (1re-hashing 得到 32 位数字的;即计算哈希(12544897317)。这样做更好,因为它不只是丢弃原始哈希值的高位,而是将它们混合到最终的哈希值中。【参考方案3】:因为哈希函数的目的是获取一组输入并将它们分布在一系列键中,所以这些键没有理由必须是正整数。
python 哈希函数返回负整数的事实只是一个实现细节,并且必然限于长整数。例如 hash('abc') 在我的系统上是负数。
【讨论】:
以上是关于Python hash() 不能处理长整数?的主要内容,如果未能解决你的问题,请参考以下文章
Python:如何将 32 位有符号长整数转换为 7 位整数
在Python中散列一个整数以匹配Oracle的STANDARD_HASH