获取numpy以警告整数溢出

时间:2022-06-20 01:54:11

Having mostly used python, I've gotten spoiled by not having to worry about integer overflow. Now that I'm using numpy, I have to worry about it again. I would like numpy to error in cases of overflow, but it doesn't seem to work for int64.

由于大部分时间都在使用python,所以不必担心整数溢出,我已经被宠坏了。现在我用的是numpy,我得再考虑一次。我希望numpy在溢出时出错,但是它对int64似乎不起作用。

import numpy
numpy.seterr(all='raise')
print("{:,}".format(numpy.prod([10]*50)))
# -5,376,172,055,173,529,600
print("{:,}".format(numpy.int64(3200000000) * numpy.int64(3200000000)))
# -8,206,744,073,709,551,616
print("{:,}".format(numpy.int32(320000) * numpy.int32(320000)))
# FloatingPointError: overflow encountered in int_scalars -- Finally getting an error!

I could always add dtype=object to fix these issues, but I would think int64 is good enough most of the time, it is just scary that it can fail in this hard to detect way.

我总是可以添加dtype=object来修复这些问题,但是我认为int64在大多数情况下已经足够好了,它可能会以这种难以检测的方式失败,这很可怕。

Why does seterr only work for int32? Can I make it work for int64?

为什么seterr只对int32有效?我能让它在int64工作吗?

The only part of the numpy.seterr docs that I can find which may hint to why this might be the case is the following short passage:

唯一的部分麻木。我能找到的,可以暗示为什么会是这样的,seterr文档是下面这段简短的文字:

Note that operations on integer scalar types (such as int16) are handled like floating point, and are affected by these settings.

注意,对整数标量类型(如int16)的操作处理类似于浮点数,并且受这些设置的影响。

But nothing in the data type docs would suggest that int32 and int64 are somehow conceptually different. Not sure if int64 is not considered an "integer scalar type".

但是,在数据类型文档中,没有任何东西表明int32和int64在概念上有什么不同。不确定int64是否被视为“整数标量类型”。

1 个解决方案

#1


2  

Indeed, the behaviour seems to be dependent on the size of the int type. Here is a list that includes your case and adds some more (having set numpy.seterr(all='raise')).

实际上,行为似乎取决于int类型的大小。这里有一个列表,其中包含了您的案例,并添加了一些内容(设置了numpy.seterr(all='raise'))。

In [25]: numpy.int(3200000000) * numpy.int(3200000000)
Out[25]: 10240000000000000000

In [26]: numpy.int8(3200000000) * numpy.int8(3200000000)
Out[26]: 0

In [27]: numpy.int16(3200000000) * numpy.int16(3200000000)
---------------------------------------------------------------------------
FloatingPointError                        Traceback (most recent call last)
<ipython-input-27-a6185c9da0fd> in <module>()
----> 1 numpy.int16(3200000000) * numpy.int16(3200000000)

FloatingPointError: overflow encountered in short_scalars

In [28]: numpy.int32(3200000000) * numpy.int32(3200000000)
---------------------------------------------------------------------------
FloatingPointError                        Traceback (most recent call last)
<ipython-input-28-a3909399b44a> in <module>()
----> 1 numpy.int32(3200000000) * numpy.int32(3200000000)

FloatingPointError: overflow encountered in int_scalars

In [29]: numpy.int64(3200000000) * numpy.int64(3200000000)
Out[29]: -8206744073709551616

#1


2  

Indeed, the behaviour seems to be dependent on the size of the int type. Here is a list that includes your case and adds some more (having set numpy.seterr(all='raise')).

实际上,行为似乎取决于int类型的大小。这里有一个列表,其中包含了您的案例,并添加了一些内容(设置了numpy.seterr(all='raise'))。

In [25]: numpy.int(3200000000) * numpy.int(3200000000)
Out[25]: 10240000000000000000

In [26]: numpy.int8(3200000000) * numpy.int8(3200000000)
Out[26]: 0

In [27]: numpy.int16(3200000000) * numpy.int16(3200000000)
---------------------------------------------------------------------------
FloatingPointError                        Traceback (most recent call last)
<ipython-input-27-a6185c9da0fd> in <module>()
----> 1 numpy.int16(3200000000) * numpy.int16(3200000000)

FloatingPointError: overflow encountered in short_scalars

In [28]: numpy.int32(3200000000) * numpy.int32(3200000000)
---------------------------------------------------------------------------
FloatingPointError                        Traceback (most recent call last)
<ipython-input-28-a3909399b44a> in <module>()
----> 1 numpy.int32(3200000000) * numpy.int32(3200000000)

FloatingPointError: overflow encountered in int_scalars

In [29]: numpy.int64(3200000000) * numpy.int64(3200000000)
Out[29]: -8206744073709551616