2012-04-04 8 views
38

teilen Wenn ich Punkt Teilung in Python Sie schwimmen, wenn ich durch Null teilen, erhalte ich eine Ausnahme:Wie NaN bekommen, wenn ich von Null

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

Ich möchte wirklich, anstatt bekommen NaN oder Inf (weil die NaN oder Inf wird durch den Rest meiner Berechnung korrekt propagieren und nicht mein Programm zu töten).

Wie kann ich das tun?

+3

Ist eigentlich "NaN" oder "Inf" durch Null dividieren? – beerbajay

+8

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

+0

Eigentlich sehr interessant wäre es, das Python-Verhalten so zu ändern, dass es wirklich für '1.0/0' funktioniert, ohne alles explizit neu zu tippen oder auszuprobieren - außer überall. – Fenikso

Antwort

48

Der einfachste Weg, um dieses Verhalten zu bekommen, ist numpy.float64 Standard float Typ anstelle von Python zu verwenden:

diese NumPy erfordert
>>> import numpy 
>>> numpy.float64(1.0)/0.0 
inf 

Natürlich. Sie können numpy.seterr() zur Feinabstimmung der Fehlerbehandlung verwenden.

+0

Das hat super funktioniert. Sie können 'numpy.float64'-Werte sogar problemlos an SWIG-Wrapped C-Bibliotheken übergeben. –

+1

Was ist der Grund dafür, dass float ('inf') 'und' float ('nan') 'in Python integriert sind, wenn Sie eine Bibliothek von Drittanbietern verwenden müssen, um das erwartete Verhalten zu erhalten? h., es scheint, als ob man 'float (' inf ')' eingeben würde, ist das einzige Mal, dass ich tatsächlich darauf zählen kann, ein von Python zurückgegebenes inf-Ergebnis zu sehen. – Brandin

+0

Wenn Sie das zum ersten Mal ausführen, wird ein Fehler ausgegeben. – becko

19

Methode 1:

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

Methode 2:

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

aber darüber im Klaren sein, dass der Wert als auch -Inf sein könnte, so dass Sie einen markanten Test machen sollten. Nichtsdestotrotz sollte Ihnen das oben die Idee geben, wie es gemacht wird.

+0

Ich finde das neue 'math.inf' ein bisschen schöner zu lesen. –

+0

@NeilG Wenn es einen gibt, sicher. Damals im Jahr 2012 gab es es noch nicht ... – glglgl

+0

Oh! Irgendwie dachte ich, das wäre eine neue Frage. Wie auch immer, es ist ab Version 3 da.5 –

6

Sie könnten versuchen, die ‚Dezimal‘ Modul:

>>> 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

Wenn ich richtig Ihr Problem zu verstehen, dann sollte dies die Lösung sein:

try: 
    1.0/0.0 
except:  
    return 'inf' 

können Sie es modifizierte Ausnahme nach verschiedenen Python Handhabungsmethode verfügbar

+6

Besser 'float ('inf')' anstelle von ''inf'' - Sie erhalten dann einen float, nicht a string ... – glglgl

+8

Besser 'außer ZeroDivisionError',' except' alleine fängt auch 'KeyboardInterrupt' etc. – Marian

-4

Ich benutzte eine Wrapper-Funktion in einem Python-Programm von mir für eine einfache Division, die ZeroDivisionError zurückgab, wenn die Sensoren ich war Verwendung wurde nicht eingesteckt. Es gibt einfach 0 (Null), was in der realen Welt ist, was ich wollte. Wahrscheinlich wird es mit mehr Variablen unordentlich, aber ...

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

Entschuldigung, ich habe vergessen, dies für das, was gefragt wurde, zu überarbeiten, aber alles, was Sie tun müssen, ist die Null auf" NaN "zu ändern Ich glaube. –

+0

Dies ist keine allgemeine Lösung. Z.B. Ich würde nicht erwarten, dass 0.0 0 ergibt, noch würde ich erwarten, dass es NaN gibt. – Brandin

Verwandte Themen