views:

157

answers:

1

I'm looking over some complex Python 2.6 code which is occasionally resulting in an infinity being generated (at least an Infinity being serialized by the json library -- which checks w/ math.isinf).

What is especially baffling is that Python (as far as I can tell) shouldn't be able to ever produce computation results set to infinity. Am I wrong with this assumption? I was aware you can only get infinities from constants:

k = float('inf')
k = 1e900
+9  A: 

Somewhere between 1e308 and 1e309 the floats run out of precision, so if you are computing results above that range you will see 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 can handle larger numbers, but obviously there is a performance penalty (and it can't be serialised with json)

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

Here is an example of an addition that doesn't raise overflow exception

>>> a=1e308
>>> a+a
inf
gnibbler
Right, the issue is that somehow that infinities are being generated through computation, not via const assignments. I'm wondering if there is anyway that OverflowExceptions would get bypassed.
UsAaR33
Sure can, I added an example to the bottom of my answer
gnibbler
You can define the JSON behavior as for gnibbler's comment on the question. You can also check for float infinity in the python code withfrom decimal import Decimalif Decimal("%f" % younumber).is_infinite(): raise OverflowError
jsbueno
Wow, gnibbler, I'm surprised that python fails to check for overflow on certain operations. Thanks a lot!
UsAaR33