2012-04-04 20 views
38

Quando faccio la divisione in virgola mobile in Python, se divido per zero, ottengo un'eccezione:Come arrivare NaN quando ho dividere per zero

>>> 1.0/0.0 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ZeroDivisionError: float division 

mi piacerebbe davvero ottenere NaN o Inf invece (perché il NaN o Inf si propagherà per il resto del mio calcolo correttamente e non uccidere il mio programma).

Come posso fare questo?

+3

È in realtà la divisione per zero 'NaN' o' Inf'? – beerbajay

+8

@beerbajay: '0.0/0.0' ->' nan', '1.0/0.0' ->' inf', '-1.0/0.0' ->' -inf'. –

+0

realtà molto interessante potrebbe essere quella di modificare il comportamento di Python in modo che davvero lavora per '1.0/0' senza ridigitare esplicitamente tutto o mettere try-tranne ovunque. – Fenikso

risposta

48

Il modo più semplice per ottenere questo comportamento è quello di utilizzare numpy.float64 al posto di Python di default tipo float:

>>> import numpy 
>>> numpy.float64(1.0)/0.0 
inf 

Naturalmente questo richiede NumPy. È possibile utilizzare numpy.seterr() per ottimizzare la gestione degli errori.

+0

Questo ha funzionato alla grande. È anche possibile passare i valori di 'numpy.float64' alle librerie C avvolte da SWIG senza problemi. –

+1

Qual è il punto di avere anche 'float ('inf')' e 'float ('nan')' integrato in Python se devi usare una libreria di terze parti per ottenere il comportamento previsto? Ad esempio, sembra che digitando 'float ('inf')' esplicitamente sia l'unica volta in cui posso effettivamente contare vedendo un risultato 'inf' restituito da Python. – Brandin

+0

La prima volta che si esegue questo, si genera un errore. – becko

19

Metodo 1:

try: 
    value = a/b 
except ZeroDivisionError: 
    value = float('Inf') 

Metodo 2:

if b != 0: 
    value = a/b 
else: 
    value = float('Inf') 

ma essere consapevoli che il valore potrebbe anche essere -Inf, così si dovrebbe fare un test più distintivo. Tuttavia, questo sopra dovrebbe darti l'idea di come farlo.

+0

Trovo la nuova 'math.inf' un po 'più bello da leggere. –

+0

@NeilG Se ce n'è uno, sicuro. Nel 2012 non esisteva ancora ... – glglgl

+0

Oh! In qualche modo ho pensato che fosse una nuova domanda. Comunque, è lì a partire dalla versione 3.5 –

6

Si potrebbe provare a utilizzare il modulo 'decimale':

>>> from decimal import * 
>>> setcontext(ExtendedContext) 
>>> inf = Decimal(1)/Decimal(0) 
>>> print(inf) 
Infinity 
>>> neginf = Decimal(-1)/Decimal(0) 
>>> print(neginf) 
-Infinity 
>>> print(neginf + inf) 
NaN 
>>> print(neginf * inf) 
-Infinity 
>>> print(dig/0) 
Infinity 
-3

Se ho ben capito il problema correttamente allora questo dovrebbe essere la soluzione:

try: 
    1.0/0.0 
except:  
    return 'inf' 

si può modificato secondo le varie eccezioni pitone metodo di trattamento disponibile

+6

Meglio 'float ('inf')' invece di ''inf'' - allora otterrai un float, non un stringa ... – glglgl

+8

Meglio "tranne ZeroDivisionError'," except' da solo prende anche 'KeyboardInterrupt' ecc. – Marian

-4

ho usato una funzione confezione in un programma pitone di miniera per una semplice divisione che tornava ZeroDivisionError quando i sensori ero usando non sono stati inseriti. Semplicemente restituisce 0 (zero), che in termini reali è ciò che volevo. Probabilmente diventa complicato con più variabili, tuttavia ...

def calculation(a, b): 
    if a == 0: 
     return 0 
    elif b == 0: 
     return 0 
    else: 
     return a/b 
+0

Scusa, ho dimenticato di rivedere questo per quello che veniva chiesto, ma tutto quello che devi fare è cambiare lo zero in" NaN " Credo. –

+0

Questa non è una soluzione generale. Per esempio. Non mi aspetterei che a/0.0 dia 0, né mi aspetto che dia NaN. – Brandin

Problemi correlati