Unterschied zwischen Möglichkeiten zum Vergleichen von Gleitkommazahlen


7

Es scheint viele Ansätze zu geben, um zu beurteilen, ob zwei Gleitkommazahlen identisch sind. Hier sind einige Beispiele, die ich gefunden habe:

  1. fabs(x - y) < n * FLT_EPSILON * fabs(x) ODER fabs(x - y) < n * FLT_EPSILON * fabs(y)

  2. fabs(x - y) < n * FLT_EPSILON * fabs(x + y)

  3. fabs(x - y) < n * FLT_EPSILON * fabs(x + y) || fabs(x - y) < FLT_MIN)

  4. fabs(x - y) < n * FLT_EPSILON * sqrt(x * x + y * y + FLT_EPSILON * FLT_EPSILON)

Ich bin wirklich verwirrt über sie. Angenommen, es gibt eine beste Möglichkeit, zwei Gleitkommazahlen zu vergleichen. Dies ist sowohl die einfachste als auch die genaueste. Die anderen Ansätze sollten nicht einmal existieren. Diese verschiedenen Wege müssen also ihre eigenen Vor- und Nachteile haben.

Meine Frage ist: Um "echte Berechnungen" durchzuführen, welcher Ansatz ist der genaueste ?


Referenzlinks:

http://accu.org/index.php/journals/1558 (1 und 4)

https://stackoverflow.com/a/10335601/5399734 (2 und 3)


2
Leider ist die numerische Analyse keine triviale Angelegenheit, und die richtige Wahl hängt möglicherweise von der Art der Berechnung ab, die Sie durchführen.
Yuval Filmus

Antworten:


2

Sie sind zu Recht verwirrt, weil diese Antworten inkompatible Konzepte zu einem richtigen Durcheinander vermischen.

Wenn Sie wissen möchten, ob zwei Gleitkommazahlen gleich sind, verwenden Sie den Operator "==", der Ihnen absolut korrekt sagt, ob sie gleich sind.

Wenn Sie wissen möchten, ob sie identisch sind, ist das etwas schwieriger: Es gibt +0 und -0, die gleich, aber nicht identisch sind, und es gibt NaNs (Not-a-Number), die nicht gleich sind, nicht einmal gleich sich selbst , kann aber identisch sein.

Wenn Sie nun Gleitkomma-Arithmetik ausführen, kann es vorkommen, dass zwei Berechnungen, die dasselbe mathematische Ergebnis hätten liefern sollen, aufgrund von Rundungsfehlern unterschiedliche Ergebnisse liefern. Es kann auch vorkommen, dass zwei Berechnungen, die unterschiedliche mathematische Ergebnisse hätten liefern sollen, dasselbe Ergebnis liefern.

Es gibt keine schnelle und einfache Regel . Sie müssen darüber nachdenken, was Ihr Ziel ist und wie Sie es erreichen können. Und jeder Fall ist anders.

PS. (4) ist einfach schrecklich. Total, total falsch. Wenn Sie doppelte Genauigkeit verwenden und eine von x, y größer als 10 ^ 160 ist, werden fast zwei beliebige Zahlen von diesem Code als "gleich" betrachtet.

PS. (1-3) sind ebenso schrecklich, weil sie behaupten, dass 0 ≠ 0 ist.

PS. (3) ist schrecklich - es zerstört die Idee eines allmählichen Unterlaufs vollständig.

PS. In der Regel sollten Sie doppelte Genauigkeit anstelle von einfacher Genauigkeit verwenden, es sei denn, Sie haben einen sehr guten Grund, dies nicht zu tun. Ein Grund, den Sie erklären und verteidigen können.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.