2009-12-01 14 views
6

Sto osservando alcuni complessi codici Python 2.6 che occasionalmente generano un infinito generato (almeno un Infinity che viene serializzato dalla libreria json - che controlla w/math.isinf).Infinity generato in python code

Ciò che è particolarmente sconcertante è che Python (per quanto posso dire) non dovrebbe essere in grado di produrre risultati di calcolo impostati su infinito. Ho sbagliato con questa ipotesi? Ero consapevole che si può ottenere solo infiniti da costanti:

k = float('inf') 
k = 1e900 
+0

Hmm ... l'infinito non è valido JSON, ma Python sia serializzare e deserializzare esso. – Thanatos

+2

@Thanatos che il comportamento è configurabile http://docs.python.org/library/json.html –

risposta

13

Da qualche parte tra 1e308 e 1e309 i galleggianti a corto di precisione, quindi se siete Computing risultati di cui sopra di tale intervallo si vedrà 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 
>>> 

decimale può gestire numeri più grandi, ma ovviamente c'è una penalizzazione delle prestazioni (e non può essere serializzata con json)

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

Ecco un esempio di un'aggiunta che non fa ra eccezione di overflow ise

>>> a=1e308 
>>> a+a 
inf 
+0

Giusto, il problema è che in qualche modo gli infiniti vengono generati attraverso il calcolo, non tramite le assegnazioni const. Mi chiedo se ci sia comunque OverflowExceptions che verrà aggirato. – UsAaR33

+0

Certo, ho aggiunto un esempio alla fine della mia risposta –

+0

È possibile definire il comportamento JSON come per il commento di gnibbler sulla domanda. Puoi anche controllare float infinity nel codice python con dall'importazione decimale Decimale se Decimal ("% f"% younumber) .is_infinite(): raise OverflowError – jsbueno