2016-05-06 9 views
1

Ich teste einige Bits Code, eine Zahl, die Berechnung mit Fließkommawerten beinhaltet - oft sehr viele davon. Ich habe einige generische (C++ - Template-Code, aber es ist nicht wichtig für diese Frage) Code, der meine Ausgaben, ob sie Skalar oder Arrays sind, gegen ihre erwarteten Werte vergleicht.Was ist eine gute Faustregel-Gleitkommavergleichsmethode?

Ich bin mit dem Problem der Wahl einer Genauigkeit Schwelle, zumindest für die beiden C/C++ Fließkomma-Typen float und double konfrontiert - für verschiedene Funktionen, die ich testen. Wie es well known gibt, gibt es keine Einheitsgröße in Bezug auf den Vergleich von Gleitkommawerten, noch einen einzelnen Genauigkeitswert, der nur auf den Datentyp passt und berechnet: Relativer vs. absoluter Fehler, zahlreiche Operationen, die sich vergrößern können Gleitkomma-Rundungsfehler viel, Berechnungen, die bei 0 ankommen sollen, so dass man sich nicht wirklich um den Erwartungswert normalisieren kann, usw.

Was ist ein allgemein vernünftiger Ansatz/Algorithmus/Faustregel? eine Vergleichsmethode (und Gleichheitsschwellenwerte) für Fließkommawerte wählen?

Antwort

0

Es gibt keine :-(

Eine wichtige Eigenschaft von Zahlen allgemein sinnvoller Ansatz ist, dass die Menge der Zahlen in Äquivalenzklassen unterteilt werden kann, in der alle Mitglieder der gleichen Äquivalenzklasse „gleich“ in gewissem Sinne sind und alle Mitglieder von zwei verschiedenen Äquivalenzklassen sind "ungleich". Diese Eigenschaft ist für Sortieralgorithmen und Hashing notwendig.

Wenn Sie doppelt mit 53 Bit Mantisse nehmen, und nur die letzten Bits der Mantisse durch Nullen ersetzen, dann Sie haben immer noch Äquivalenzklassen, und Sortieren/Hashing wird gut funktionieren, auf der anderen Seite können zwei Zahlen beliebig nahe beieinander liegen und immer noch mit gleich vergleichen diese Methode.

Die andere Methode hat einen Algorithmus, der entscheidet, ob zwei Zahlen "möglicherweise gleich" sind. Sie können alles andere darauf aufbauen. Zum Beispiel ist a "definitiv größer" als b, wenn a> b und a nicht "möglicherweise gleich" zu b ist. a ist "möglicherweise größer" als b, wenn a> b oder a "möglicherweise gleich" zu b ist.

Sortierung ist problematisch. Sie könnten ein "möglicherweise gleich" zu b und b "möglicherweise gleich" zu c haben, aber a ist nicht "möglicherweise gleich" zu c.

Wenn Sie double mit 53 Bit Mantisse verwenden, ist es unwahrscheinlich, dass zwei nicht verwandte Zahlen innerhalb von sogar 45 Bit gleich sind. Man kann also ganz vernünftig prüfen, ob der absolute Wert der Differenz kleiner ist als der absolute Wert der größeren Zahl geteilt durch 2^45. Ihre Laufleistung wird erheblich variieren. Wichtig ist, ob Sie denken, dass 0 sehr kleinen Zahlen gleich sein sollte oder nicht.

1

Ich mag den Ansatz in Googletest, z. EXPECT_DOUBLE_EQ (a, b) und EXPECT_FLOAT_EQ (a, b): Die Zahlen sind ungefähr gleich, wenn sie an der letzten Position (4 ULP) innerhalb von 4 Einheiten liegen. Um dies zu tun, Sie

  1. convert unterzeichnet-Größe
  2. subtrahieren zum Ausgleich, als ob sie ganze Zahlen waren
  3. prüfen, ob die Differenz < = 4.

Diese automatisch Größe skaliert und entspannt bis absolut nahe Null.