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

use*_*863 15 python cython python-3.x

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
Run Code Online (Sandbox Code Playgroud)

产生此错误:"OverflowError:Python int太大而无法转换为C long"

我也尝试将它们声明为unsigned longs.我用什么类型来处理非常大的数字?如果它对于交流时间太大有任何解决方法吗?

sha*_*unc 6

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


And*_*lov 5

cythonpyx文件编译为C,因此它依赖于基础C编译器。

C中整数类型的大小在不同的平台和操作系统上会有所不同,并且C标准并不要求确切的实现。

但是,实际上存在实现约定。

Windows的32位和64位都使用和的4个字节(32位),int和使用long8个字节(64位)的字节long long。Win32和Win64之间的区别是指针的大小(Win32为32位,Win64为64位)。(请参阅MSDN中的“ 数据类型范围 ”)。

Linux使用另一种模型:intlinux-32和linux-64均为32位,long long始终为64位。long指针是不同的:Linux-32上为32位,Linux-64上为64位。

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

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

如果您需要任意精度的数字,则可以使用GMP库 -实际上是高精度算术的标准。Python有一个名为gmpy2的包装器。