Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get numpy to warn on integer overflow

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.

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.

Why does seterr only work for int32? Can I make it work for 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:

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

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".

like image 892
Dan Avatar asked Aug 14 '15 16:08

Dan


1 Answers

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')).

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
like image 94
Ramon Crehuet Avatar answered Nov 20 '22 07:11

Ramon Crehuet