Obter numpy para avisar sobre estouro de inteiro

9

Tendo usado principalmente o python, eu não sou incomodado com estouro de inteiro. Agora que estou usando numpy, tenho que me preocupar com isso novamente. Eu gostaria de numpy para erro em casos de estouro, mas não parece funcionar para 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!

Eu sempre poderia adicionar dtype=object para corrigir esses problemas, mas eu acho que o int64 é bom o suficiente na maioria das vezes, é apenas assustador que ele possa falhar nesse modo difícil de detectar.

Por que o seterr funciona apenas para o int32? Posso fazer isso funcionar para o int64?

A única parte dos documentos numpy.seterr que eu posso encontrar o que pode sugerir porque este pode ser o caso é a seguinte passagem curta:

  

Observe que as operações em tipos escalares inteiros (como int16) são   manipulados como ponto flutuante e são afetados por essas configurações.

Mas nada nos documentos tipo de dados sugere que int32 e int64 sejam de alguma forma conceitualmente diferente. Não tenho certeza se int64 não é considerado um "tipo escalar inteiro".

    
por Dan 14.08.2015 в 18:02
fonte

1 resposta

2

De fato, o comportamento parece depender do tamanho do tipo int. Aqui está uma lista que inclui o seu caso e adiciona um pouco mais (tendo definido 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
    
por Ramon Crehuet 11.01.2016 / 16:53
fonte