Pregunta

Estoy revisando algún código complejo de Python 2.6 que ocasionalmente genera un infinito (al menos un Infinity serializado por la biblioteca json, que verifica w / math.isinf).

Lo que es especialmente desconcertante es que Python (por lo que puedo decir) no debería ser capaz de producir resultados de cómputo establecidos en infinito. ¿Estoy equivocado con esta suposición? Sabía que solo puedes obtener infinitos de constantes:

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

Solución

En algún lugar entre 1e308 y 1e309, los flotadores se quedan sin precisión, por lo que si está calculando resultados por encima de ese rango, 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 puede manejar números más grandes, pero obviamente hay una penalización de rendimiento (y no se puede serializar con json)

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

Aquí hay un ejemplo de una adición que no genera una excepción de desbordamiento

>>> a=1e308
>>> a+a
inf
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top