numpy数组中的整数溢出

kam*_*ame 8 python numpy

import numpy as np
a = np.arange(1000000).reshape(1000,1000)
print(a**2)
Run Code Online (Sandbox Code Playgroud)

有了这段代码,我得到了这个答案.为什么我会得到负值?

[[         0          1          4 ...,     994009     996004     998001]
 [   1000000    1002001    1004004 ...,    3988009    3992004    3996001]
 [   4000000    4004001    4008004 ...,    8982009    8988004    8994001]
 ..., 
 [1871554624 1873548625 1875542628 ..., -434400663 -432404668 -430408671]
 [-428412672 -426416671 -424420668 ..., 1562593337 1564591332 1566589329]
 [1568587328 1570585329 1572583332 ..., -733379959 -731379964 -729379967]]
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 18

在您的平台上,np.arange返回一个dtype'int32'数组:

In [1]: np.arange(1000000).dtype
Out[1]: dtype('int32')
Run Code Online (Sandbox Code Playgroud)

数组的每个元素都是32位整数.Squaring导致结果不适合32位.结果被裁剪为32位并仍然被解释为32位整数,但这就是您看到负数的原因.

编辑:在这种情况下,你可以通过在平方之前构造一个dtype'int64'数组来避免整数溢出:

a=np.arange(1000000,dtype='int64').reshape(1000,1000)
Run Code Online (Sandbox Code Playgroud)

请注意,您使用numpy时发现的问题是一个固有的危险.你必须小心选择你的dtypes并且事先知道你的代码不会导致算术溢出.为了速度,numpy不会也不会在发生这种情况时发出警告.

有关numpy邮件列表的讨论,请参见http://mail.scipy.org/pipermail/numpy-discussion/2009-April/041691.html.


小智 5

python整数没有此问题,因为它们溢出时会自动升级为python长整数。

因此,如果您确实设法溢出了int64,则一种解决方案是在numpy数组中使用python int:

import numpy
a=numpy.arange(1000,dtype=object)
a**20
Run Code Online (Sandbox Code Playgroud)

  • 使用对象对性能有何影响? (4认同)