Хеш Python () не может обработать длинное целое?

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

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 хеш () функция дает отрицательное целое число?

9
задан Xie 22 April 2010 в 02:14
поделиться

3 ответа

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

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

10
ответ дан 4 December 2019 в 10:03
поделиться

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

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

4
ответ дан 4 December 2019 в 10:03
поделиться

См. объект .__ hash __

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

Изменено в версии 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
7
ответ дан 4 December 2019 в 10:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: