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 inf
Wert 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 inf
Wert wird als ein ganz besonderer Wert mit ungewöhnlicher Semantik betrachtet. Es ist daher besser, OverflowError
sofort über eine Ausnahme Bescheid zu wissen , als einen inf
Wert 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 inf
oder ist -inf
, gibt es entweder 0.0
oder 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:
+inf
ist höher als-inf
-inf
ist niedriger als+inf
+inf
ist weder höher noch niedriger als+inf
-inf
ist weder höher noch niedriger als -inf
NaN
ist falsch ( inf
weder höher noch niedriger als NaN
)Im Vergleich zur Gleichheit +inf
und +inf
sind gleich, wie -inf
und -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 +inf
ist ungleich -inf
und alles, einschließlich sich NaN
selbst, 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:
NaN
0.0
oder -0.0
².NaN
.inf - inf
ist das Ergebnis undefiniert : NaN
;inf - -inf
, ist das Ergebnis inf
;-inf - inf
, ist das Ergebnis -inf
;-inf - -inf
ist das Ergebnis undefiniert : NaN
.inf + inf
, ist das Ergebnis inf
;inf + -inf
ist das Ergebnis undefiniert : NaN
;-inf + inf
ist das Ergebnis undefiniert : NaN
;-inf + -inf
, ist das Ergebnis -inf
.math.pow
, pow
oder **
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 inf
oder ist -inf
, verhält es sich korrekt und gibt entweder inf
oder 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.exp
leidet 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.0
Ausbeute inf
.
Hinweis 2: Da jede Berechnung mit NaN
Rückgaben NaN
und jeder Vergleich mit NaN
, einschließlich sich NaN
selbst, erfolgt false
, sollten Sie die math.isnan
Funktion 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 NaN
intern kein Anmelden vorhanden ist . Wenn Sie teilen -inf / +inf
, ist das Ergebnis NaN
nicht -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.0
und -1/ float(-inf)
Renditen 0.0
. Darüber hinaus 0.0 == -0.0
isttrue
, 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/x
Bruchteil ist x = 1e-323
es inf
aber wann x = 1e-324
oder 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!
1e309
als interpretiert wird+inf
und-1e309
als interpretiert wird-inf
.