Es hängt vom Fließkommaformat ab und insbesondere davon, ob allmählicher Unterlauf vorliegt. IEEE 754 binäre Fließkommazahl. Das bedeutet, dass die Lücke zwischen zwei verschiedenen Floats immer ungleich Null ist, auch wenn sie im Extremfall nur mit einem signifikanten Bit dargestellt werden kann.
Die kleinstmögliche absolute Differenz zwischen zwei unterschiedlichen Gleitkommazahlen wird mit einem Gleichheitszeichen (oder einer der Zahlen Null), einem Exponenten mit der Nummer Null und mit einem Unterschied von 1 erhalten. In diesem Fall würde die Subtraktion des Größeren vom Kleineren zum Kleinsten führen Magnitude negative Zahl, mit negativem Vorzeichen, Null Exponent und Signifikand 1. Diese Zahl vergleicht weniger als Null.
Es gibt andere Berechnungen, die zu Null unterlaufen. Wenn Sie zum Beispiel die kleinste positive Zahl durch eine Zahl größer oder gleich zwei dividieren, erhalten Sie im normalen Rundungsmodus den Wert Null.
[Diese Antwort ist als Ergänzung zu der schönen Antwort von Patricia Shanahan gedacht. Diese Antwort deckt den Normalfall ab; Hier sorgen wir uns über Randfälle, die Sie in der Praxis wahrscheinlich nicht vorfinden.]
Ja, das ist absolut möglich. Hier ist eine Python-Sitzung von meinem sehr gewöhnlichen Intel-basierten Mac-Laptop:
%Vor% Natürlich, wie der Import zeigt, ist hier etwas Böses im Gange. Hier sind die Inhalte von evil.py
. (Achtung: Dies ist sehr plattformspezifisch und funktioniert wie beschrieben nur unter OS X. Variationen davon sollten unter Linux / x64 funktionieren, vorausgesetzt, Python wurde kompiliert, um die SSE2-Anweisungen anstelle der x87-Einheit für Fließkommaoperationen zu verwenden Ich habe keine Ahnung von Windows.)
Was wir hier machen, ist also mit den FPU-Einstellungen im MXCSR-Steuerregister zu tun. Auf Intel 64-Prozessoren, die die SSE-Befehlssätze unterstützen, gibt es zwei interessante Flags, die das Verhalten von Operationen mit subnormalen Zahlen beeinflussen. Das Flag FTZ (flush-to-zero) bewirkt, wenn es gesetzt ist, dass jede subnormale Ausgabe einer arithmetischen Operation durch Null ersetzt wird. Das DAZ-Flag (denormalals-are-zero) bewirkt, wenn es gesetzt ist, dass jede subnormale Eingabe für eine arithmetische Operation so behandelt wird, als wäre sie null. Der Sinn dieser Flags besteht darin, dass sie Vorgänge mit subnormalen Zahlen erheblich beschleunigen können, wobei die Konformität mit dem IEEE-754-Standard verloren geht. Im obigen Code haben wir das FTZ-Flag im MXCSR-Steuerregister gesetzt.
Und jetzt wählen wir a
und b
, so dass sowohl a
als auch b
normal sind, aber ihre Differenz ist subnormal. Dann wird a < b
(wie üblich) wahr sein, aber a - b
wird -0.0
sein, und der Vergleich a - b < 0
schlägt fehl.
Der Take-away-Punkt ist, dass es nicht ausreicht, dass das Fließkomma Format , das Sie verwenden, ein IEEE 754-Format ist. Sie müssen auch wissen, dass Ihre Operationen dem Standard entsprechen. Der FTZ-Modus ist ein Beispiel für einen möglichen Fehler. Um dies mit Patricia Shanahans Antwort in Verbindung zu bringen: Der Code in evil.py
schaltet den allmählichen Unterlauf ab, den IEEE 754 verspricht. (Danke @EricPostpischil für den Hinweis in den Kommentaren.)
Sie können leicht durch einige der "Ecken Fälle" wie diese
gehen %Vor%Tags und Links python floating-point