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

Python 整数 长整数 浮点数 字符串 列表 元组 字典的各种方法

python 基础 7 数据类型

简明Python教程笔记