Python hash()无法处理长整数?

时间:2010-04-22 02:14:33

标签: python hash integer

我定义了一个类:

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

为什么在doctest中,hash()函数给出一个负整数?

3 个答案:

答案 0 :(得分:10)

似乎仅限于32位。通过阅读this question,您的代码可能会在64位计算机上产生预期结果(具有这些特定值,因为结果适合64位)。

内置hash函数的结果取决于平台,并受限于本机字大小。如果您需要确定性的跨平台哈希,请考虑使用hashlib模块。

答案 1 :(得分: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

答案 2 :(得分:4)

因为散列函数的目的是获取一组输入并将它们分布在一系列键中,所以没有理由这些键必须是正整数。

pythons散列函数返回负整数的事实只是一个实现细节,并且必须限于长整数。例如,hash('abc')在我的系统上是否定的。