Die allgemeine Weisheit, dass Gleitkommazahlen nicht auf Gleichheit verglichen werden können, ist ungenau. Gleitkommazahlen unterscheiden sich nicht von ganzen Zahlen: Wenn Sie "a == b" auswerten, erhalten Sie true, wenn es sich um identische Zahlen handelt, und andernfalls false (mit dem Verständnis, dass zwei NaNs natürlich keine identischen Zahlen sind).
Das eigentliche Problem ist folgendes: Wenn ich einige Berechnungen durchgeführt habe und nicht sicher bin, ob die beiden Zahlen, die ich vergleichen muss, genau richtig sind, was dann? Dieses Problem ist für Gleitkommazahlen dasselbe wie für Ganzzahlen. Wenn Sie den ganzzahligen Ausdruck "7/3 * 3" auswerten, wird er nicht mit "7 * 3/3" verglichen.
Nehmen wir also an, wir fragten: "Wie vergleiche ich ganze Zahlen auf Gleichheit?" in solch einer Situation. Es gibt keine einzige Antwort; Was Sie tun sollten, hängt von der jeweiligen Situation ab, insbesondere davon, welche Art von Fehlern Sie haben und was Sie erreichen möchten.
Hier sind einige mögliche Optionen.
Wenn Sie ein "wahres" Ergebnis erhalten möchten, wenn die mathematisch exakten Zahlen gleich wären, können Sie versuchen, die Eigenschaften der von Ihnen durchgeführten Berechnungen zu verwenden, um zu beweisen, dass Sie die gleichen Fehler in den beiden Zahlen erhalten. Wenn dies machbar ist und Sie zwei Zahlen vergleichen, die sich aus Ausdrücken ergeben, die bei genauer Berechnung gleiche Zahlen ergeben würden, erhalten Sie aus dem Vergleich "wahr". Ein anderer Ansatz besteht darin, dass Sie die Eigenschaften der Berechnungen analysieren und nachweisen können, dass der Fehler niemals einen bestimmten Betrag überschreitet, möglicherweise einen absoluten Betrag oder einen Betrag relativ zu einer der Eingaben oder einer der Ausgaben. In diesem Fall können Sie fragen, ob sich die beiden berechneten Zahlen um höchstens diesen Betrag unterscheiden, und "true" zurückgeben, wenn sie innerhalb des Intervalls liegen. Wenn Sie keine Fehlergrenze nachweisen können, Sie könnten raten und auf das Beste hoffen. Eine Möglichkeit zu raten besteht darin, viele Zufallsstichproben auszuwerten und festzustellen, welche Art von Verteilung Sie in den Ergebnissen erhalten.
Da wir nur festlegen, dass Sie "wahr" werden, wenn die mathematisch genauen Ergebnisse gleich sind, haben wir natürlich die Möglichkeit offen gelassen, dass Sie "wahr" werden, auch wenn sie ungleich sind. (Tatsächlich können wir die Anforderung erfüllen, indem wir immer "true" zurückgeben. Dies vereinfacht die Berechnung, ist jedoch im Allgemeinen unerwünscht. Daher werde ich die Verbesserung der folgenden Situation erörtern.)
Wenn Sie ein "falsches" Ergebnis erhalten möchten, wenn die mathematisch genauen Zahlen ungleich wären, müssen Sie nachweisen, dass Ihre Bewertung der Zahlen unterschiedliche Zahlen ergibt, wenn die mathematisch genauen Zahlen ungleich wären. Dies kann aus praktischen Gründen in vielen häufigen Situationen unmöglich sein. Betrachten wir also eine Alternative.
Eine nützliche Anforderung könnte sein, dass wir ein "falsches" Ergebnis erhalten, wenn sich die mathematisch genauen Zahlen um mehr als einen bestimmten Betrag unterscheiden. Zum Beispiel werden wir vielleicht berechnen, wohin ein in einem Computerspiel geworfener Ball gereist ist, und wir wollen wissen, ob er einen Schläger getroffen hat. In diesem Fall möchten wir auf jeden Fall "wahr" werden, wenn der Ball auf den Schläger trifft, und wir möchten "falsch" werden, wenn der Ball weit vom Schläger entfernt ist, und wir können eine falsche "wahre" Antwort akzeptieren, wenn der Ball eintritt Eine mathematisch exakte Simulation hat den Schläger verfehlt, ist aber nur einen Millimeter vom Schlagen des Schlägers entfernt. In diesem Fall müssen wir beweisen (oder raten / schätzen), dass unsere Berechnung der Position des Balls und der Position des Schlägers einen kombinierten Fehler von höchstens einem Millimeter aufweist (für alle interessierenden Positionen). Dies würde es uns ermöglichen, immer zurückzukehren "
Wie Sie beim Vergleich von Gleitkommazahlen entscheiden, was zurückgegeben werden soll, hängt also stark von Ihrer spezifischen Situation ab.
Dies kann ein kompliziertes Thema sein, wenn es darum geht, Fehlergrenzen für Berechnungen nachzuweisen. Jede Gleitkommaimplementierung unter Verwendung des IEEE 754-Standards im Rund-zu-Nächsten-Modus gibt die Gleitkommazahl zurück, die dem exakten Ergebnis für jede Grundoperation (insbesondere Multiplikation, Division, Addition, Subtraktion, Quadratwurzel) am nächsten kommt. (Im Falle eines Gleichstands rund, damit das niedrige Bit gerade ist.) (Seien Sie besonders vorsichtig bei Quadratwurzel und Division; Ihre Sprachimplementierung verwendet möglicherweise Methoden, die für diese nicht IEEE 754 entsprechen.) Aufgrund dieser Anforderung kennen wir die Der Fehler in einem einzelnen Ergebnis beträgt höchstens die Hälfte des Wertes des niedrigstwertigen Bits. (Wenn es mehr wäre, wäre die Rundung auf eine andere Zahl gegangen, die innerhalb der Hälfte des Wertes liegt.)
Von dort aus wird es wesentlich komplizierter. Der nächste Schritt ist die Ausführung einer Operation, bei der einer der Eingänge bereits einen Fehler aufweist. Bei einfachen Ausdrücken können diese Fehler durch die Berechnungen verfolgt werden, um eine Grenze für den endgültigen Fehler zu erreichen. In der Praxis geschieht dies nur in wenigen Situationen, beispielsweise bei der Arbeit an einer hochwertigen Mathematikbibliothek. Und natürlich müssen Sie genau steuern, welche Vorgänge genau ausgeführt werden. Hochsprachen geben dem Compiler häufig viel Spielraum, sodass Sie möglicherweise nicht wissen, in welcher Reihenfolge Operationen ausgeführt werden.
Es könnte (und wird) noch viel mehr über dieses Thema geschrieben werden, aber ich muss hier aufhören. Zusammenfassend lautet die Antwort: Für diesen Vergleich gibt es keine Bibliotheksroutine, da es keine einzige Lösung gibt, die den meisten Anforderungen entspricht und die es wert ist, in eine Bibliotheksroutine aufgenommen zu werden. (Wenn der Vergleich mit einem relativen oder absoluten Fehlerintervall für Sie ausreicht, können Sie dies einfach ohne Bibliotheksroutine tun.)