使用带有大型int的cython时会发生溢出错误

时间:2014-11-12 01:42:03

标签: python python-3.x cython

python 3.4,windows 10,cython 0.21.1

我正在使用cython

将此函数编译为c
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长度太大有任何解决方法吗?

2 个答案:

答案 0 :(得分:6)

如果确保计算在c中(例如,声明i为long,并将数据元素放入cdefed变量或在计算之前将其强制转换),则不会出现此错误。但是,您的实际结果可能因平台而异,具体取决于(可能)生成的精确汇编代码以及由此产生的溢出处理。有更好的算法,正如@ cod3monk3y所指出的那样(查看“简单校验和”链接)。

答案 1 :(得分:4)

cython pyx 文件编译为C,因此它依赖于底层的C编译器。

C中整数类型的大小因不同的平台和操作系统而异,C标准并未规定确切的实现。

然而,事实上的实施惯例。

32位和64位的Windows对intlong使用4个字节(32位),对long long使用8个字节(64位)。 Win32和Win64之间的区别是指针的大小(Win32为32位,Win64为64位)。 (请参阅MSDN上的Data Type Ranges]。

Linux使用另一种模式:int对于linux-32和linux-64都是32位,long long总是64位。 long和指针有所不同:linux-32上为32位,linux-64上为64位。

长话短说:如果您需要在不同平台上未更改的整数类型的最大容量,请使用long long(或unsigned long long)。

long long的数据范围为[–9223372036854775808, 9223372036854775807]

如果需要具有任意精度的数字,则GMP library - 高精度算术的事实上的标准。 Python有一个名为gmpy2的包装器。