为什么对大整数的操作会悄无声息地溢出?

问题描述 投票:0回答:2

我有一个包含非常大整数的列表,我想将其转换为 pandas 列。例如,

2**31
超出了int32 dtype的限制。然后将其转换为 dtype int32 列会引发溢出错误,这让我知道要使用另一个 dtype 或提前以某种方式处理该数字。

但是,如果一个数字很大但在 dtype 限制之内(即

2**31-1
),并且向其中添加了一些数字,这应该会导致一个值超出 dtype 限制,而不是引发溢出错误,则操作是执行时没有任何错误,但该值现在已反转并且是一个完全错误的数字。

import pandas as pd
pd.Series([2**31], dtype='int32')        # <--- OverflowError: Python int too large to convert to C long

pd.Series([2**31-1], dtype='int32') + 1

0   -2147483648
dtype: int32

为什么会这样?

PS。我在 Python 3.11.5 上使用 pandas 2.1.0。

python pandas long-integer
2个回答
0
投票

不是 100% 确定,但作为有根据的猜测:

第一次溢出发生在Python和C之间的边界,并且在转换过程中检测到溢出。然而,第二次溢出完全发生在 C 内部,其中不存在整数溢出检查。


0
投票

让我们来了解一下:

import pandas as pd
s = pd.Series([2**31-1], dtype='int32')
type(s[0])
type((pd.Series([2**31-1], dtype='int32') + 1)[0])
type(s[0] + 1)
pd.Series([1,2,3], dtype='int32') + 1
<class 'numpy.int32'>
<class 'numpy.int32'>
<class 'numpy.int64'>
0    2
1    3
2    4
dtype: int32

Pandas 对

Series
执行加法运算并强制执行类型。 Numpy 在访问
Series
(类型:
numpy.int32
)的元素并执行加法时接管。 Numpy 将类型强制为
numpy.int64
以避免溢出。

© www.soinside.com 2019 - 2024. All rights reserved.