Python hash () не может обработать длинное целое число? - PullRequest
9 голосов
/ 22 апреля 2010

Я определил класс:

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 ]

10 голосов
/ 22 апреля 2010

Похоже, что он ограничен 32-разрядными. Читая этот вопрос , похоже, что ваш код мог дать ожидаемый результат на 64-битной машине (с этими конкретными значениями, поскольку результат умещается в 64 бит).

Результаты встроенной функции hash зависят от платформы и ограничены собственным размером слова. Если вам нужен детерминированный кроссплатформенный хеш, рассмотрите возможность использования модуля hashlib.

7 голосов
/ 22 апреля 2010

См. object.__hash__

Обратите внимание, что

Изменено в версии 2.5: __hash__() теперь может также возвращать длинный целочисленный объект;32-разрядное целое число затем получается из хеша этого объекта.

В вашем случае ожидаемый 12544897317L - это объект с длинным целым числом,

Python выводит 32-бит целое -340004569 по (12544897317 & 0xFFFFFFFF) - (1<<32)

32-битное целое число, полученное Python по хэшу (12544897317L), что приводит к -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
4 голосов
/ 22 апреля 2010

Поскольку целью хэш-функции является получение набора входных данных и их распределение по диапазону ключей, нет причин, по которым эти ключи должны быть положительными целыми числами.Функция возвращает отрицательные целые числа - это просто деталь реализации и обязательно ограничена длинными целыми числами.Например, хэш ('abc') отрицателен в моей системе.

...