2009-12-01 9 views
6

Je regarde un code Python 2.6 complexe qui génère occasionnellement un infini généré (au moins un Infinity étant sérialisé par la bibliothèque json - qui vérifie w/math.isinf). Ce qui est particulièrement déroutant, c'est que Python (pour autant que je sache) ne puisse jamais produire de résultats de calcul à l'infini. Est-ce que j'ai tort avec cette hypothèse? Je savais que vous ne pouvez obtenir infinités de constantes:Infinity généré en code python

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

Hmm ... infinity n'est pas un JSON valide, mais Python va à la fois le sérialiser et le désérialiser. – Thanatos

+2

@Thanatos ce comportement est configurable http://docs.python.org/library/json.html –

Répondre

13

Quelque part entre 1e308 et 1e309 les flotteurs à court de précision, donc si vous le calcul des résultats ci-dessus cette gamme, vous verrez 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 
>>> 

décimal peut gérer un plus grand nombre, mais de toute évidence il y a une pénalité de performance (et il ne peut pas être publié en feuilleton avec JSON)

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

Voici un exemple d'un ajout qui ne ra Exception de débordement ise

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

À droite, le problème est que d'une manière ou d'une autre les infinis sont générés par le calcul, pas par l'intermédiaire d'affectations const. Je me demande s'il y a de toute façon que OverflowExceptions serait contournée. – UsAaR33

+0

Bien sûr, j'ai ajouté un exemple au bas de ma réponse –

+0

Vous pouvez définir le comportement JSON comme pour le commentaire de gnibbler sur la question. Vous pouvez également vérifier l'infini flottant dans le code python avec d'importation décimal décimal si décimal (« % f » % younumber) .is_infinite(): augmentation OverflowError – jsbueno