Python 运行时警告:长整型遇到溢出

92 投票
2 回答
318026 浏览
提问于 2025-04-17 03:07

我刚开始学习编程。在我最近的Python 2.7项目中遇到了以下问题:

运行时警告:在长整型计算中遇到溢出

有人能详细解释一下这是什么意思吗?我该怎么解决这个问题呢?

代码虽然能运行,但我不确定忽略这个警告是否是个好主意。

这个问题发生在一个添加数据的过程中,比如:

SomeList.append(VeryLongFormula)

2 个回答

27

解决这个问题的一个简单方法是使用64位类型

my_list = numpy.array(my_list, dtype=numpy.float64)
90

这里有一个例子,它会发出相同的警告:

import numpy as np
np.seterr(all='warn')
A = np.array([10])
a=A[-1]
a**a

结果是

RuntimeWarning: overflow encountered in long_scalars

在上面的例子中,问题出在 a 的数据类型是 int32,而 int32 能存储的最大值是 2 的 31 次方减去 1。因为 10 的 10 次方 大于 2 的 32 次方减去 1,所以计算的结果会是一个超出 int32 能存储的范围的数字。

需要注意的是,你不能完全依赖 np.seterr(all='warn') 来捕捉所有的溢出错误。在 32 位的 NumPy 中:

>>> np.multiply.reduce(np.arange(21)+1)
-1195114496

而在 64 位的 NumPy 中:

>>> np.multiply.reduce(np.arange(21)+1)
-4249290049419214848

这两种情况都会失败,但没有任何警告,虽然这也是因为溢出错误。正确的答案是 21 的阶乘等于:

In [47]: import math

In [48]: math.factorial(21)
Out[50]: 51090942171709440000L

根据 NumPy 开发者 Robert Kern 的说法

与真正的浮点错误不同(在浮点运算中,硬件会在发生溢出时设置一个标志),我们需要自己实现整数溢出的检测。我们在标量上做这个,但在数组上不这样做,因为对数组的每个原子操作进行检测会太慢。

所以,选择合适的数据类型 dtypes 是你的责任,以确保没有操作会导致溢出。

撰写回答