Was wäre der effizienteste Weg, um zwei double
oder zwei float
Werte zu vergleichen ?
Einfach das zu tun ist nicht richtig:
bool CompareDoubles1 (double A, double B)
{
return A == B;
}
Aber so etwas wie:
bool CompareDoubles2 (double A, double B)
{
diff = A - B;
return (diff < EPSILON) && (-diff < EPSILON);
}
Scheint Abfallverarbeitung.
Kennt jemand einen intelligenteren Float-Vergleicher?
<invoke Knuth>
Vorzeitige Optimierung ist die Wurzel allen Übels.</invoke Knuth>
Gehen Sie einfach mit abs (ab) <EPS wie oben angegeben, es ist klar und leicht zu verstehen.==
kann die Verwendung vollkommen richtig sein, aber dies hängt ganz von dem Kontext ab, der in der Frage nicht angegeben ist. Bis dieser Kontext bekannt ist,==
bleibt immer noch der "effizienteste Weg" .Antworten:
Seien Sie äußerst vorsichtig mit den anderen Vorschlägen. Es hängt alles vom Kontext ab.
Ich habe lange Zeit damit verbracht, Fehler in einem System aufzuspüren,
a==b
bei dem davon ausgegangen wurde, dass|a-b|<epsilon
. Die zugrunde liegenden Probleme waren:Die implizite Annahme in einem Algorithmus, dass wenn
a==b
undb==c
danna==c
.Verwenden des gleichen Epsilons für Linien in Zoll und Linien in Mil (0,001 Zoll). Das ist
a==b
aber1000a!=1000b
. (Aus diesem Grund fragt AlmostEqual2sComplement nach dem epsilon oder max ULPS.)Die Verwendung des gleichen Epsilons sowohl für den Kosinus der Winkel als auch für die Länge der Linien!
Verwenden einer solchen Vergleichsfunktion zum Sortieren von Elementen in einer Sammlung. (In diesem Fall führte die Verwendung des integrierten C ++ - Operators == für Doppel zu korrekten Ergebnissen.)
Wie ich schon sagte: Es hängt alles vom Kontext und der erwarteten Größe von
a
und abb
.Übrigens
std::numeric_limits<double>::epsilon()
ist das "Maschinen-Epsilon". Dies ist die Differenz zwischen 1,0 und dem nächsten Wert, der durch ein Doppel dargestellt werden kann. Ich denke, dass es in der Vergleichsfunktion verwendet werden könnte, aber nur, wenn die erwarteten Werte kleiner als 1 sind. (Dies ist eine Antwort auf die Antwort von @ cdv ...)Wenn Sie im Grunde genommen
int
Arithmetik habendoubles
(hier verwenden wir in bestimmten Fällen Doubles, um int-Werte zu halten), ist Ihre Arithmetik korrekt. Zum Beispiel ist 4.0 / 2.0 dasselbe wie 1.0 + 1.0. Dies gilt, solange Sie keine Aktionen ausführen, die zu Brüchen (4.0 / 3.0) führen, oder die Größe eines Int nicht überschreiten.quelle
fabs(a)+fabs(b)
NaN, 0 Summe und Überlauf machen, dies wird jedoch recht komplex.float
/double
ist MANTISSA x 2 ^ EXP .epsilon
wird vom Exponenten abhängig sein. Wenn zum Beispiel die Mantisse 24 Bit ist und der Exponent 8 Bit vorzeichenbehaftet ist, dann ist1/(2^24)*2^127
oder~2^103
einepsilon
für einige Werte; oder bezieht sich dies auf ein minimales epsilon ?|a-b|<epsilon
, ist nicht richtig. Bitte fügen Sie diesen Link Ihrer Antwort hinzu. Wenn Sie damit einverstanden sind, kann cygnus-software.com/papers/comparingfloats/comparingfloats.htm und ich meine dummen Kommentare entfernen.Der Vergleich mit einem Epsilon-Wert ist das, was die meisten Leute tun (sogar in der Spielprogrammierung).
Sie sollten Ihre Implementierung jedoch ein wenig ändern:
Bearbeiten: Christer hat in einem kürzlich veröffentlichten Blog-Beitrag einen Stapel großartiger Informationen zu diesem Thema hinzugefügt . Genießen.
quelle
float a = 3.4; if(a == 3.4){...}
dh wenn Sie einen gespeicherten Gleitkomma mit einem Literal | vergleichen In diesem Fall werden beide Zahlen gespeichert, sodass sie dieselbe Darstellung haben, wenn sie gleich sind. Was ist also der Schaden, wenn Sie dies tuna == b
?EPSILON
definiert alsDBL_EPSILON
. Normalerweise wird ein bestimmter Wert ausgewählt, der von der erforderlichen Genauigkeit des Vergleichs abhängt.EPSILON
Der Vergleich funktioniert nicht, wenn die Floats groß sind, da der Unterschied zwischen aufeinanderfolgenden Floats ebenfalls groß wird. Siehe diesen Artikel .EPSILON
ist ziemlich nutzlos. Sie müssen mit einem Schwellenwert vergleichen, der für die jeweiligen Einheiten sinnvoll ist. Verwendenstd::abs
Sie es auch, da es für verschiedene Gleitkommatypen überladen ist.Ich fand heraus, dass das Google C ++ Testing Framework eine nette plattformübergreifende vorlagenbasierte Implementierung von AlmostEqual2sComplement enthält, die sowohl auf Doubles als auch auf Floats funktioniert. Da es unter der BSD-Lizenz veröffentlicht wird, sollte die Verwendung in Ihrem eigenen Code kein Problem sein, solange Sie die Lizenz behalten. Ich habe den folgenden Code aus
http://code.google.com/p/googletest/source/browse/trunk/include/gtest/internal/gtest-internal.hhttps://github.com/google/googletest/blob extrahiert /master/googletest/include/gtest/internal/gtest-internal.h und fügte die Lizenz oben hinzu.Stellen Sie sicher, dass Sie #EST GTEST_OS_WINDOWS auf einen bestimmten Wert definieren (oder den Code, in dem er verwendet wird, in einen Wert ändern, der zu Ihrer Codebasis passt - schließlich ist er BSD-lizenziert).
Anwendungsbeispiel:
Hier ist der Code:
EDIT: Dieser Beitrag ist 4 Jahre alt. Es ist wahrscheinlich immer noch gültig und der Code ist nett, aber einige Leute haben Verbesserungen gefunden. Am besten holen Sie sich die neueste Version von
AlmostEquals
direkt aus dem Google Test-Quellcode und nicht die, die ich hier eingefügt habe.quelle
Der Vergleich von Gleitkommazahlen für hängt vom Kontext ab. Da selbst das Ändern der Reihenfolge der Operationen zu unterschiedlichen Ergebnissen führen kann, ist es wichtig zu wissen, wie "gleich" die Zahlen sein sollen.
Der Vergleich von Gleitkommazahlen von Bruce Dawson ist ein guter Ausgangspunkt für den Gleitkommavergleich.
Die folgenden Definitionen stammen aus der Kunst der Computerprogrammierung von Knuth :
Die Auswahl von epsilon hängt natürlich vom Kontext ab und bestimmt, wie gleich die Zahlen sein sollen.
Eine andere Methode zum Vergleichen von Gleitkommazahlen besteht darin, den ULP (Einheiten an letzter Stelle) der Zahlen zu betrachten. Das Papier Was jeder Informatiker über Gleitkommazahlen wissen sollte, ist eine gute Quelle, um zu verstehen, wie Gleitkommazahlen funktionieren und welche Fallstricke es gibt, einschließlich der Frage, was ULP ist.
quelle
fabs(a - b) <= ( (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon);
hat mein Leben gerettet. LOL Beachten Sie, dass diese Version (ich habe nicht überprüft, ob sie auch für die anderen gilt) auch die Änderung berücksichtigt, die im integralen Teil der Gleitkommazahl auftreten kann (Beispiel:2147352577.9999997616 == 2147352576.0000000000
Hier können Sie deutlich erkennen, dass es fast einen Unterschied von gibt2
zwischen den beiden Zahlen) was ganz nett ist! Dies geschieht, wenn der akkumulierte Rundungsfehler den Dezimalteil der Zahl überschreitet.std::max(std::abs(a), std::abs(b))
(oder mitstd::min()
) geschrieben werden.std::abs
In C ++ ist es mit Float- und Double-Typen überladen, sodass es einwandfrei funktioniert (Sie können diefabs
Lesbarkeit jedoch jederzeit beibehalten).Weitere Informationen finden Sie unter Vergleichen von Gleitkommazahlen . Hier ist das Code-Snippet von diesem Link:
quelle
*(int*)&A;
" gegen strenge Aliasing-Regeln verstoßen?Die Erkenntnis, dass dies ein alter Thread ist, aber dieser Artikel ist einer der einfachsten, den ich beim Vergleichen von Gleitkommazahlen gefunden habe. Wenn Sie mehr darüber erfahren möchten, enthält er auch detailliertere Referenzen und die Hauptseite deckt eine ganze Reihe von Themen ab Umgang mit Gleitkommazahlen Der Gleitkomma-Leitfaden: Vergleich .
Wir finden einen etwas praktischeren Artikel in Gleitkommatoleranzen überarbeitet und stellen fest, dass es einen absoluten Toleranztest gibt , der in C ++ darauf hinausläuft:
und relativer Toleranztest :
Der Artikel stellt fest , dass der absolute Test schlägt fehl , wenn
x
undy
ist groß und nicht in dem relativen Fall , wenn sie klein sind. Unter der Annahme, dass die absolute und relative Toleranz gleich sind, würde ein kombinierter Test folgendermaßen aussehen:quelle
Der tragbare Weg, um epsilon in C ++ zu bekommen, ist
Dann wird die Vergleichsfunktion
quelle
Am Ende habe ich einige Zeit damit verbracht, Material in diesem großartigen Thread durchzugehen. Ich bezweifle, dass jeder so viel Zeit verbringen möchte, um die Zusammenfassung meiner Erkenntnisse und die von mir implementierte Lösung hervorzuheben.
Kurze Zusammenfassung
numeric_limits::epsilon()
die gleiche wie FLT_EPSILON in float.h. Dies ist jedoch problematisch, da epsilon zum Vergleichen von Werten wie 1.0 nicht mit epsilon zum Vergleichen von Werten wie 1E9 identisch ist. Das FLT_EPSILON ist für 1.0 definiert.fabs(a-b) <= epsilon
funktioniert jedoch nicht, da das Standard-Epsilon für 1.0 definiert ist. Wir müssen Epsilon in Bezug auf a und b nach oben oder unten skalieren.max(a,b)
oder Sie können die nächsten darstellbaren Zahlen um a erhalten und dann prüfen, ob b in diesen Bereich fällt. Ersteres wird als "relative" Methode und später als ULP-Methode bezeichnet.Implementierung von Dienstprogrammfunktionen (C ++ 11)
quelle
isDefinitelyLessThan
prüftdiff < tolerance
, was bedeutet, dass a und b fast gleich sind (und somit ist a nicht definitiv kleiner als b). Ist es nicht sinnvoller, in beiden Fällen die Diff> Toleranz zu überprüfen? Oder fügen Sie einorEqualTo
Argument hinzu, das steuert, ob die ungefähre Gleichheitsprüfung true zurückgeben soll oder nicht.Der Code, den Sie geschrieben haben, ist fehlerhaft:
Der richtige Code wäre:
(... und ja das ist anders)
Ich frage mich, ob Fabs Sie in einigen Fällen nicht dazu bringen würden, die faule Bewertung zu verlieren. Ich würde sagen, es hängt vom Compiler ab. Vielleicht möchten Sie beide ausprobieren. Wenn sie im Durchschnitt gleichwertig sind, nehmen Sie die Implementierung mit fabs.
Wenn Sie Informationen darüber haben, welcher der beiden Floats mit größerer Wahrscheinlichkeit größer ist als der andere, können Sie in der Reihenfolge des Vergleichs spielen, um die verzögerte Bewertung besser nutzen zu können.
Schließlich können Sie ein besseres Ergebnis erzielen, wenn Sie diese Funktion einbinden. Es ist jedoch unwahrscheinlich, dass sich viel verbessert ...
Edit: OJ, danke für die Korrektur deines Codes. Ich habe meinen Kommentar entsprechend gelöscht
quelle
Dies ist in Ordnung, wenn:
Aber sonst bringt es dich in Schwierigkeiten. Zahlen mit doppelter Genauigkeit haben eine Auflösung von etwa 16 Dezimalstellen. Wenn die beiden Zahlen, die Sie vergleichen, größer sind als EPSILON * 1.0E16, können Sie genauso gut sagen:
Ich werde einen anderen Ansatz untersuchen, bei dem davon ausgegangen wird, dass Sie sich um das erste Problem kümmern müssen, und davon, dass das zweite Problem für Ihre Anwendung in Ordnung ist. Eine Lösung wäre so etwas wie:
Dies ist rechenintensiv, aber manchmal erforderlich. Dies müssen wir in meinem Unternehmen tun, da es sich um eine technische Bibliothek handelt und die Eingaben um einige Dutzend Größenordnungen variieren können.
Auf jeden Fall geht es darum (und gilt für praktisch jedes Programmierproblem): Bewerten Sie Ihre Anforderungen und finden Sie dann eine Lösung, um Ihre Anforderungen zu erfüllen. Gehen Sie nicht davon aus, dass die einfache Antwort Ihren Anforderungen entspricht. Wenn Sie nach Ihrer Bewertung feststellen, dass dies
fabs(a-b) < EPSILON
ausreicht, perfekt - verwenden Sie es! Beachten Sie jedoch auch die Mängel und andere mögliche Lösungen.quelle
Wie andere bereits betont haben, ist die Verwendung eines Epsilons mit festem Exponenten (z. B. 0,0000001) für Werte außerhalb des Epsilon-Werts unbrauchbar . Wenn Ihre beiden Werte beispielsweise 10000.000977 und 10000 sind, gibt es zwischen diesen beiden Zahlen KEINE 32-Bit-Gleitkommawerte - 10000 und 10000.000977 liegen so nahe wie möglich, ohne bitweise identisch zu sein. Hier ist ein Epsilon von weniger als 0,0009 bedeutungslos; Sie können auch den geraden Gleichheitsoperator verwenden.
Wenn sich die beiden Werte einer Größe von epsilon nähern, wächst der relative Fehler ebenfalls auf 100%.
Der Versuch, eine Festkommazahl wie 0,00001 mit Gleitkommawerten (wobei der Exponent beliebig ist) zu mischen, ist daher sinnlos. Dies funktioniert immer nur, wenn Sie sicher sein können, dass die Operandenwerte in einem engen Bereich liegen (dh in der Nähe eines bestimmten Exponenten), und wenn Sie einen Epsilon-Wert für diesen bestimmten Test richtig auswählen. Wenn Sie eine Zahl aus der Luft ziehen ("Hey! 0.00001 ist klein, das muss also gut sein!"), Sind Sie zu numerischen Fehlern verurteilt. Ich habe viel Zeit damit verbracht, schlechten numerischen Code zu debuggen, bei dem ein armer Trottel zufällige Epsilon-Werte einwirft, damit ein weiterer Testfall funktioniert.
Wenn Sie numerische Programmierungen jeglicher Art durchführen und glauben, dass Sie nach Festpunkt-Epsilons greifen müssen, LESEN SIE BRUCES ARTIKEL ZUM VERGLEICH VON SCHWIMMUNGSPUNKTNUMMERN .
Gleitkommazahlen vergleichen
quelle
Qt implementiert zwei Funktionen, vielleicht können Sie daraus lernen:
Und möglicherweise benötigen Sie die folgenden Funktionen, da
quelle
Der allgemeine Vergleich von Gleitkommazahlen ist im Allgemeinen bedeutungslos. Wie man vergleicht, hängt wirklich von einem Problem ab. Bei vielen Problemen sind Zahlen ausreichend diskretisiert, um sie innerhalb einer bestimmten Toleranz vergleichen zu können. Leider gibt es genauso viele Probleme, bei denen ein solcher Trick nicht wirklich funktioniert. Betrachten Sie zum Beispiel die Arbeit mit einer Heaviside- (Schritt-) Funktion einer fraglichen Zahl (digitale Aktienoptionen kommen in den Sinn), wenn Ihre Beobachtungen sehr nahe an der Barriere liegen. Ein toleranzbasierter Vergleich würde nicht viel nützen, da das Problem effektiv von der ursprünglichen Barriere auf zwei neue verschoben würde. Auch hier gibt es keine universelle Lösung für solche Probleme, und die spezielle Lösung erfordert möglicherweise eine Änderung der numerischen Methode, um Stabilität zu erreichen.
quelle
Leider ist sogar Ihr "verschwenderischer" Code falsch. EPSILON ist der kleinste Wert, der zu 1.0 addiert und sein Wert geändert werden kann. Der Wert 1.0 ist sehr wichtig - größere Zahlen ändern sich nicht, wenn sie zu EPSILON hinzugefügt werden. Jetzt können Sie diesen Wert auf die Zahlen skalieren, die Sie vergleichen, um festzustellen, ob sie unterschiedlich sind oder nicht. Der richtige Ausdruck für den Vergleich zweier Doppel ist:
Dies ist ein Minimum. Im Allgemeinen sollten Sie jedoch das Rauschen in Ihren Berechnungen berücksichtigen und einige der niedrigstwertigen Bits ignorieren, sodass ein realistischerer Vergleich folgendermaßen aussehen würde:
Wenn Ihnen die Vergleichsleistung sehr wichtig ist und Sie den Bereich Ihrer Werte kennen, sollten Sie stattdessen Festkommazahlen verwenden.
quelle
EPSILON
in der FrageDBL_EPSILON
oderFLT_EPSILON
? Das Problem liegt in Ihrer eigenen Vorstellung, wo SieDBL_EPSILON
Code, der ihn nicht verwendet hat , ersetzt haben (was in der Tat die falsche Wahl wäre).Meine Klasse basiert auf zuvor veröffentlichten Antworten. Sehr ähnlich zu Googles Code, aber ich verwende einen Bias, der alle NaN-Werte über 0xFF000000 verschiebt. Dies ermöglicht eine schnellere Überprüfung auf NaN.
Dieser Code soll das Konzept demonstrieren und keine allgemeine Lösung sein. Der Code von Google zeigt bereits, wie alle plattformspezifischen Werte berechnet werden, und ich wollte das alles nicht duplizieren. Ich habe diesen Code nur begrenzt getestet.
quelle
Hier ist der Beweis, dass die Verwendung
std::numeric_limits::epsilon()
nicht die Antwort ist - sie schlägt bei Werten größer als eins fehl:Beweis meines obigen Kommentars:
Laufen ergibt diese Ausgabe:
Beachten Sie, dass im zweiten Fall (eins und nur größer als eins) die beiden Eingabewerte so nahe wie möglich sind und dennoch als nicht nahe verglichen werden. Für Werte größer als 1,0 können Sie daher auch einfach einen Gleichheitstest verwenden. Feste Epsilons sparen Sie beim Vergleich von Gleitkommawerten nicht.
quelle
return *(reinterpret_cast<double*>(&x));
obwohl es normalerweise funktioniert, ist es tatsächlich undefiniertes Verhalten.numeric_limits<>::epsilon
IEEE 754-Bodenpunkt zu demonstrieren .Eine weitere interessante Implementierung wurde gefunden unter: https://en.cppreference.com/w/cpp/types/numeric_limits/epsilon
quelle
Ich wäre sehr vorsichtig mit diesen Antworten, die eine Gleitkommasubtraktion beinhalten (z. B. fabs (ab) <epsilon). Erstens werden die Gleitkommazahlen bei größeren Größen und bei ausreichend großen Größen, bei denen der Abstand größer als epsilon ist, spärlicher. Sie können auch einfach a == b ausführen. Zweitens erhalten Sie durch das Subtrahieren von zwei sehr engen Gleitkommazahlen (wie dies normalerweise der Fall ist, wenn Sie nach nahezu Gleichheit suchen) eine katastrophale Stornierung .
Obwohl nicht tragbar, denke ich, dass die Antwort von grom diese Probleme am besten vermeidet.
quelle
a
und fürb
sich. Es gibt absolut kein Problem mit der Verwendung der Gleitkommasubtraktion als Teil eines Fuzzy-Vergleichs (obwohl, wie andere gesagt haben, ein absoluter Epsilon-Wert für einen bestimmten Anwendungsfall geeignet sein kann oder nicht.)Es gibt tatsächlich Fälle in numerischer Software, in denen Sie überprüfen möchten, ob zwei Gleitkommazahlen genau gleich sind. Ich habe dies auf eine ähnliche Frage gestellt
https://stackoverflow.com/a/10973098/1447411
Man kann also nicht sagen, dass "CompareDoubles1" im Allgemeinen falsch ist.
quelle
Dies hängt davon ab, wie genau der Vergleich sein soll. Wenn Sie für genau die gleiche Zahl vergleichen möchten, gehen Sie einfach mit ==. (Sie möchten dies fast nie tun, es sei denn, Sie möchten tatsächlich genau dieselbe Nummer.) Auf jeder anständigen Plattform können Sie auch Folgendes tun:
da
fabs
neigt dazu, ziemlich schnell zu sein. Mit ziemlich schnell meine ich, dass es im Grunde ein bitweises UND ist, also ist es besser, schnell zu sein.Ganzzahlige Tricks zum Vergleichen von Double und Floats sind nett, erschweren jedoch die effektive Handhabung der verschiedenen CPU-Pipelines. Und es ist heutzutage definitiv nicht schneller auf bestimmten in-order-Architekturen, da der Stack als temporärer Speicherbereich für Werte verwendet wird, die häufig verwendet werden. (Load-Hit-Store für diejenigen, die sich interessieren.)
quelle
In Bezug auf den Mengenumfang:
Wenn
epsilon
der kleine Bruchteil der Größe der Menge (dh der relative Wert) in einem bestimmten physikalischen Sinne undA
undB
Typen in demselben Sinne vergleichbar ist, denke ich, dass das Folgende ganz richtig ist:quelle
Ich benutze diesen Code:
quelle
epsilon
.epsilon
ist lediglich der Abstand zwischen 1 und der nächsten darstellbaren Zahl nach 1. Am besten, dass Code nur zu überprüfen versucht , ob die beiden Zahlen sind genau gleich zueinander, sondern weil nicht-Potenzen von 2 multipliziert werdenepsilon
es, macht das nicht mal richtig.std::fabs(std::min(v1, v2))
ist falsch - für negative Eingänge wählt es den mit der größeren Größe.Ich schreibe das für Java, aber vielleicht findest du es nützlich. Es verwendet Longs anstelle von Doubles, kümmert sich jedoch um NaNs, Subnormen usw.
Beachten Sie, dass sich die Anzahl nach einer Reihe von Gleitkommaoperationen stark von unseren Erwartungen unterscheiden kann. Es gibt keinen Code, um das zu beheben.
quelle
Wie wäre es damit?
Ich habe verschiedene Ansätze gesehen - aber noch nie gesehen, deshalb bin ich auch neugierig auf Kommentare!
quelle
Ich habe diese Funktion für mein kleines Projekt verwendet und sie funktioniert, aber beachten Sie Folgendes:
Fehler mit doppelter Genauigkeit können eine Überraschung für Sie sein. Angenommen, epsilon = 1.0e-6, dann sollten 1.0 und 1.000001 gemäß dem obigen Code NICHT als gleich angesehen werden. Auf meinem Computer werden sie jedoch von der Funktion als gleich angesehen. Dies liegt daran, dass 1.000001 nicht präzise in ein Binärformat übersetzt werden kann. es ist wahrscheinlich 1.0000009xxx. Ich teste es mit 1.0 und 1.0000011 und diesmal erhalte ich das erwartete Ergebnis.
quelle
Dies ist eine weitere Lösung mit Lambda:
quelle
Mein Weg ist vielleicht nicht richtig, aber nützlich
Konvertieren Sie beide float in Strings und vergleichen Sie dann die Strings
Eine Überlappung des Operators kann ebenfalls durchgeführt werden
quelle
Sie können nicht zwei
double
mit einem festen vergleichenEPSILON
. Abhängig vom Wert vondouble
,EPSILON
variiert.Ein besserer Doppelvergleich wäre:
quelle
Allgemeiner ausgedrückt:
quelle
a
undb
bereits kleiner alsepsilon()
dort sind, kann der Unterschied immer noch signifikant sein. Umgekehrt, wenn die Zahlen sehr groß sind, schlägt der Vergleich bereits nach ein paar Fehlerbits fehl, selbst wenn Sie möchten, dass die Zahlen als gleich angesehen werden. Diese Antwort ist genau die Art von "generischem" Vergleichsalgorithmus, den Sie vermeiden möchten.Warum nicht bitweises XOR durchführen? Zwei Gleitkommazahlen sind gleich, wenn ihre entsprechenden Bits gleich sind. Ich denke, die Entscheidung, die Exponentenbits vor der Mantisse zu platzieren, wurde getroffen, um den Vergleich zweier Floats zu beschleunigen. Ich denke, vielen Antworten hier fehlt der Punkt des Epsilon-Vergleichs. Der Epsilon-Wert hängt nur davon ab, mit welcher Genauigkeit Gleitkommazahlen verglichen werden. Wenn Sie beispielsweise mit Floats rechnen, erhalten Sie zwei Zahlen: 2.5642943554342 und 2.5642943554345. Sie sind nicht gleich, aber für die Lösung sind nur 3 Dezimalstellen von Bedeutung. Dann sind sie gleich: 2,564 und 2,564. In diesem Fall wählen Sie epsilon gleich 0,001. Ein Epsilon-Vergleich ist auch mit bitweisem XOR möglich. Korrigieren Sie mich, wenn ich falsch liege.
quelle