Я определил класс:
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 хеш () функция дает отрицательное целое число?
Похоже, он ограничен 32 битами. Читая этот вопрос , похоже, что ваш код мог дать ожидаемый результат на 64-битной машине (с этими конкретными значениями, поскольку результат соответствует 64 битам).
Результаты встроенной хэш-функции
зависят от платформы и ограничиваются собственным размером слова. Если вам нужен детерминированный кроссплатформенный хэш, рассмотрите возможность использования модуля hashlib
.
Поскольку цель хеш-функции состоит в том, чтобы взять набор входных данных и распределить их по диапазону ключей, нет причин, по которым эти ключи должны быть натуральными числами.
Тот факт, что хеш-функция pythons возвращает отрицательные целые числа, является лишь деталью реализации и обязательно ограничивается длинными целыми числами. Например, в моей системе значение hash ('abc') отрицательное.
Обратите внимание, что
Изменено в версии 2.5:
__ hash __ ()
может теперь также возвращать длинный целочисленный объект; {{1} } 32-битное целое число затем получается из хэша этого объекта.
В вашем случае ожидаемый 12544897317L - это длинный целочисленный объект,
Python получил 32-битное целое число -340004569 с помощью (12544897317 & 0xFFFFFFFF) - (1 << 32)
Python получил 32-разрядное целое число -340004569. -битное целое число по хешу (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