Pergunta

Eu estou olhando para algum código complexo Python 2.6, que é ocasionalmente resultando em uma infinidade sendo gerado (pelo menos uma infinidade sendo serializado pela biblioteca JSON - que verifica w / math.isinf).

O que é especialmente desconcertante é que Python (tanto quanto eu posso dizer) não deve ser capaz de resultados de computação produzem nunca pôs ao infinito. Am I errado com essa suposição? Eu estava ciente de que você só pode obter infinidades de constantes:

k = float('inf')
k = 1e900
Foi útil?

Solução

Em algum lugar entre 1e308 e 1e309 os carros alegóricos ficar sem precisão, por isso, se você está computando resultados acima dessa faixa, você verá inf

>>> 1e308
1e+308
>>> 1e309
inf

>>> json.dumps(1e308,allow_nan=False)
'1e+308'
>>> json.dumps(1e309,allow_nan=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/json/__init__.py", line 237, in dumps
    **kw).encode(obj)
  File "/usr/lib/python2.6/json/encoder.py", line 367, in encode
    chunks = list(self.iterencode(o))
  File "/usr/lib/python2.6/json/encoder.py", line 304, in _iterencode
    yield floatstr(o, self.allow_nan)
  File "/usr/lib/python2.6/json/encoder.py", line 47, in floatstr
    raise ValueError(msg)
ValueError: Out of range float values are not JSON compliant: inf
>>> 

Decimal pode lidar com números maiores, mas, obviamente, há uma penalidade de desempenho (e não pode ser serializado com JSON)

>>> from decimal import Decimal
>>> Decimal('1e900')/10
Decimal("1E+899")

Aqui está um exemplo de uma adição que não levanta exceção de estouro

>>> a=1e308
>>> a+a
inf
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top