Antworten:
Sie können immer noch NaN-Werte (Not-a-Number) durch einfache Arithmetik erhalten, die Folgendes umfasst inf:
>>> 0 * float("inf")
nan
Beachten Sie, dass Sie in der Regel nicht eine bekommen infWert durch übliche arithmetische Berechnungen:
>>> 2.0**2
4.0
>>> _**2
16.0
>>> _**2
256.0
>>> _**2
65536.0
>>> _**2
4294967296.0
>>> _**2
1.8446744073709552e+19
>>> _**2
3.4028236692093846e+38
>>> _**2
1.157920892373162e+77
>>> _**2
1.3407807929942597e+154
>>> _**2
Traceback (most recent call last):
File "<stdin>", line 1, in ?
OverflowError: (34, 'Numerical result out of range')
Der infWert wird als ein ganz besonderer Wert mit ungewöhnlicher Semantik betrachtet. Es ist daher besser, OverflowErrorsofort über eine Ausnahme Bescheid zu wissen , als einen infWert stillschweigend in Ihre Berechnungen einfließen zu lassen.
**scheint eigentlich ein bisschen fehlerhaft . Wenn es mit reellen Zahlen überläuft, gibt es einen Fehler aus, aber wenn einer seiner Operanden infoder ist -inf, gibt es entweder 0.0oder zurück inf. Es funktioniert also korrekt, wenn die Eingabe unendlich ist, aber nicht, wenn das Ergebnis unendlich sein sollte.
Die Implementierung von Python folgt ziemlich gut dem IEEE-754-Standard , den Sie als Richtlinie verwenden können, basiert jedoch auf dem zugrunde liegenden System, auf dem es kompiliert wurde, sodass Plattformunterschiede auftreten können. Kürzlich¹ wurde ein Fix angewendet, der sowohl "unendlich" als auch "inf" zulässt , aber das ist hier von untergeordneter Bedeutung.
Die folgenden Abschnitte gelten gleichermaßen für jede Sprache, die IEEE-Gleitkomma-Arithmetik korrekt implementiert. Sie ist nicht nur für Python spezifisch.
Beim Umgang mit unendlich und Operatoren, die größer >oder kleiner als <sind, zählt Folgendes:
+infist höher als-inf-infist niedriger als+inf +infist weder höher noch niedriger als+inf-inf ist weder höher noch niedriger als -infNaNist falsch ( infweder höher noch niedriger als NaN)Im Vergleich zur Gleichheit +infund +infsind gleich, wie -infund -inf. Dies ist ein viel diskutiertes Thema und mag für Sie kontrovers klingen, aber es ist im IEEE-Standard und Python verhält sich einfach so.
Natürlich +infist ungleich -infund alles, einschließlich sich NaNselbst, ist ungleich NaN.
Die meisten Berechnungen mit unendlich ergeben unendlich, es sei denn, beide Operanden sind unendlich, wenn die Operation Division oder Modulo oder bei Multiplikation mit Null einige spezielle Regeln zu beachten sind:
NaN0.0oder -0.0².NaN.inf - infist das Ergebnis undefiniert : NaN;inf - -inf, ist das Ergebnis inf;-inf - inf, ist das Ergebnis -inf;-inf - -infist das Ergebnis undefiniert : NaN.inf + inf, ist das Ergebnis inf;inf + -infist das Ergebnis undefiniert : NaN;-inf + infist das Ergebnis undefiniert : NaN;-inf + -inf, ist das Ergebnis -inf.math.pow, powoder **ist schwierig, da es nicht benimmt , wie es sollte. Es wird eine Überlaufausnahme ausgelöst, wenn das Ergebnis mit zwei reellen Zahlen zu hoch ist, um auf einen Float mit doppelter Genauigkeit zu passen (es sollte unendlich zurückgeben), aber wenn die Eingabe infoder ist -inf, verhält es sich korrekt und gibt entweder infoder zurück 0.0. Wenn das zweite Argument ist NaN, wird es zurückgegeben NaN, es sei denn, das erste Argument ist 1.0. Es gibt weitere Probleme, die nicht alle in den Dokumenten behandelt werden .math.expleidet die gleichen Probleme wie math.pow. Eine Lösung, um dies für einen Überlauf zu beheben, besteht darin, ähnlichen Code zu verwenden:
try:
res = math.exp(420000)
except OverflowError:
res = float('inf')Anmerkung 1: Als zusätzliche Einschränkung, die gemäß IEEE-Standard definiert ist, ist das Ergebnis, wenn Ihr Berechnungsergebnis unter- oder überläuft, kein Unter- oder Überlauffehler, sondern eine positive oder negative Unendlichkeit: 1e308 * 10.0Ausbeute inf.
Hinweis 2: Da jede Berechnung mit NaNRückgaben NaNund jeder Vergleich mit NaN, einschließlich sich NaNselbst, erfolgt false, sollten Sie die math.isnanFunktion verwenden, um festzustellen, ob eine Zahl tatsächlich ist NaN.
Hinweis 3: Obwohl Python das Schreiben unterstützt float('-NaN'), wird das Zeichen ignoriert, da NaNintern kein Anmelden vorhanden ist . Wenn Sie teilen -inf / +inf, ist das Ergebnis NaNnicht -NaN(so etwas gibt es nicht).
Hinweis 4: Achten Sie darauf, dass Sie sich auf die oben genannten Punkte verlassen, da Python auf der C- oder Java-Bibliothek basiert, für die es kompiliert wurde, und nicht alle zugrunde liegenden Systeme dieses Verhalten korrekt implementieren. Wenn Sie sicher sein möchten, testen Sie vor den Berechnungen auf Unendlich.
¹) In letzter Zeit bedeutet seit Version 3.2 .
²) Gleitkommazahlen unterstützen positive und negative Nullen, also: x / float('inf')behält Vorzeichen und -1 / float('inf')Renditen -0.0, 1 / float(-inf)Renditen -0.0, 1 / float('inf')Renditen 0.0und -1/ float(-inf)Renditen 0.0. Darüber hinaus 0.0 == -0.0isttrue , müssen Sie manuell die Zeichen , wenn Sie es wahr sein nicht wollen.
-1 * float('infinity') == -inf
Das Gleiche gilt für C99 .
Die von allen modernen Prozessoren verwendete IEEE 754-Gleitkommadarstellung weist mehrere spezielle Bitmuster auf, die für positive Unendlichkeit (Vorzeichen = 0, exp = ~ 0, frac = 0), negative Unendlichkeit (Vorzeichen = 1, exp = ~ 0, frac = 0) reserviert sind ) und viele NaN (keine Zahl: exp = ~ 0, frac ≠ 0).
Alles, worüber Sie sich Sorgen machen müssen: Einige Arithmetiken können Gleitkomma-Ausnahmen / Traps verursachen, aber diese sind nicht nur auf diese "interessanten" Konstanten beschränkt.
OverflowError.
Ich habe eine Einschränkung gefunden, die bisher niemand erwähnt hat. Ich weiß nicht, ob es in praktischen Situationen häufig vorkommt, aber hier ist es der Vollständigkeit halber.
Normalerweise gibt sich die Berechnung einer Zahl Modulo Infinity als Float zurück, aber ein Bruchteil Modulo Infinity gibt zurück nan(keine Zahl). Hier ist ein Beispiel:
>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan
Ich habe ein Problem mit dem Python-Bug-Tracker gemeldet. Es kann unter https://bugs.python.org/issue32968 eingesehen werden .
Update: Dies wird in Python 3.8 behoben .
Eine sehr schlechte Höhle: Division durch Null
in einem 1/xBruchteil ist x = 1e-323es infaber wann x = 1e-324oder wenig es wirftZeroDivisionError
>>> 1/1e-323
inf
>>> 1/1e-324
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero
also sei vorsichtig!
1e309als interpretiert wird+infund-1e309als interpretiert wird-inf.