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

Xie*_*Xie 9 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()函数给出一个负整数?

Fog*_*ird 10

它似乎限于32位.通过阅读这个问题,看起来您的代码可能在64位计算机上产生了预期的结果(具有这些特定值,因为结果适合64位).

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


inv*_*inv 7

看到 object.__hash__

请注意

在版本2.5中更改:__hash__()现在也可以返回一个长整数对象; 然后从该对象的散列派生32位整数.

在您的情况下,预期12544897317L是一个长整数对象,

Python派生出32位整数-340004569 (12544897317 & 0xFFFFFFFF) - (1<<32)

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
Run Code Online (Sandbox Code Playgroud)

  • Nitpick:(12544897317和0xFFFFFFFF) - (1 << 32)不是-340004569; 这是-340004571.Python实际上通过*re-hashing*获得了32位数; 即,计算哈希(12544897317).这样做更好,因为它不会丢弃原始哈希值的高位,而是将它们混合到最终的哈希值中. (2认同)