OverflowError возникает при использовании cython с большим int

python 3.4, windows 10, cython 0.21.1

Я компилирую эту функцию в c cython

def weakchecksum(data):
   """
   Generates a weak checksum from an iterable set of bytes.
   """
   cdef long a, b, l
   a = b = 0
   l = len(data)
   for i in range(l):
       a += data[i]
       b += (l - i)*data[i]

   return (b << 16) | a, a, b

который производит эту ошибку: "OverflowError: Python int слишком большой, чтобы преобразовать в C long"

Я также пробовал объявлять их как unsigned longs. Какой тип я использую для работы с действительно большими числами? Если он слишком велик для длинных c, существуют ли какие-либо обходные пути?

Ответ 1

Если вы убедитесь, что ваши вычисления находятся в c (например, объявите я длинным и поместите элемент данных в переменную cdefed или внесите его перед вычислением), вы не получите эту ошибку. Однако ваши фактические результаты могут варьироваться в зависимости от платформы, зависящей (потенциально) от точного кода сборки и итоговой обработки переполнения. Для этого есть лучшие алгоритмы, как заметил @cod3monk3y (посмотрите ссылку "простые контрольные суммы" ).

Ответ 2

cython компилирует файлы pyx на C, поэтому он зависит от основного компилятора C.

Размер целых типов в C зависит от разных платформ и операционных систем, а стандарт C не диктует точную реализацию.

Однако существуют фактические соглашения об осуществлении.

Windows для 32 и 64 бит использует 4 байта (32 бита) для int и long, 8 байтов (64 бит) для long long. Разница между Win32 и Win64 - это размер указателя (32 бит для Win32 и 64 бит для Win64). (См. Диапазоны типов данных] из MSDN).

Linux использует другую модель: int - 32 бита для linux-32 и linux-64, long long всегда 64-бит. long и указатели различаются: 32 бит на linux-32 и 64 бит на linux-64.

Короче говоря: если вам нужна максимальная емкость для целочисленного типа, которая не изменяется на разных платформах, используйте long long (или unsigned long long).

Диапазон данных для long long равен [–9223372036854775808, 9223372036854775807].

Если вам нужны номера с произвольной точностью, библиотека GMP - стандарт де-факто для высокоточной арифметики. У Python есть оболочка, называемая gmpy2.