Python的hash()无法处理长整型?
我定义了一个类:
class A: ''' hash test class >>> a = A(9, 1196833379, 1, 1773396906) >>> hash(a) -340004569 This is weird, 12544897317L expected. ''' def __init__(self, a, b, c, d): self.a = a self.b = b self.c = c self.d = d def __hash__(self): return self.a * self.b + self.c * self.d
为什么在测试中,hash()函数会返回一个负整数呢?
3 个回答
4
哈希函数的目的是把一组输入分散到一系列的键上,所以这些键不一定非得是正整数。
在Python中,哈希函数返回负整数只是实现上的一个细节,而且只限于长整型。例如,在我的系统上,hash('abc')的结果是负数。
7
请查看 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
10
看起来这个限制在32位系统上。根据这个问题,你的代码在64位机器上可能得到了预期的结果(因为那些特定的值可以在64位中表示)。
内置的hash
函数的结果是依赖于平台的,并且受到本地字长的限制。如果你需要一个稳定的、跨平台的哈希值,可以考虑使用hashlib
模块。