BOOST_CHECK_CLOSE und BOOST_CHECK_CLOSE_FRACTION (Verständnis?)Problem
-
Hallo,
ich versuche gerade die im Betreff genannten Testmacros richtig zu verwenden.
wenn ich die Doku richtig verstanden habe, dann tested
BOOST_CHECK_CLOSE
ob die Differenz von A und B grösser ist als angegben in % an 3ter Stelle
und
BOOST_CHECK_CLOSE_FRACTION
ob die Differenz von A und B grösser ist als der gegebene Wert an 3ter Stellejetzt hab ich folgendes, und eigentlich sollte das funktioniern, dachte ich zumindest.
a) BOOST_CHECK_CLOSE( std::cos(1.5708) , 0.0, 0.01 ) ; b) BOOST_CHECK_CLOSE_FRACTION( std::cos(1.5708) , 0.0, 0.00001 ) ;geht aber beides nicht. Testreport ist:
a) difference{inf%} between std::cos(1.5708){-3.6732051033465739e-06} and 0.0{0} exceeds 0.01% b) difference{1.79769e+308} between std::cos(1.5708){-3.6732051033465739e-06} and 0.0{0} exceeds 1.0000000000000001e-05Beim Ersten kann ich mir vielleicht vorstellen das 0.01 % von 0 ein Problem ist,
das Zweite dachte ich aber es sollte auf jeden Fall funktioniern, aber anscheinend denke ich nicht richtig.Kann mir bitte jemand sagen was ich falsch mache?
-
Beides sind relative Toleranzen. Beim ersten Makro ist der Wert für die Toleranz in Prozent anzugeben, beim zweiten absolut (also 0.5 wären 50%).
-
SeppJ schrieb:
Beides sind relative Toleranzen. Beim ersten Makro ist der Wert für die Toleranz in Prozent anzugeben, beim zweiten absolut (also 0.5 wären 50%).
ok, danke,
damit is mal klar das ich BOOST_CHECK_CLOSE_FRACTION falsch verstanden habewarum der Vergleich von quasi 0 mit 0 nicht geht is mir aber noch immer ein Rätsel.
brutforce wert , 0.01 bis 1
BOOST_CHECK_CLOSE( std::cos(1.5708) , 0.0, 0.01 ) ; BOOST_CHECK_CLOSE_FRACTION( std::cos(1.5708) , 0.0, 0.01 ) ; BOOST_CHECK_CLOSE( std::cos(1.5708) , 0.0, 0.1 ) ; BOOST_CHECK_CLOSE_FRACTION( std::cos(1.5708) , 0.0, 0.1 ) ; BOOST_CHECK_CLOSE( std::cos(1.5708) , 0.0, 1 ) ; BOOST_CHECK_CLOSE_FRACTION( std::cos(1.5708) , 0.0, 1 ) ;all melden einen Fehler,
wie teste ich also 2 so kleine Werte?
ich hab mir das da gemacht
template<typename T> bool in_margin(T a, T b, T c) { return std::abs(a-b) <= std::abs(c); }da funktiniert wenigstens so
BOOST_CHECK( in_margin(std::cos(1.5708) , 0.0, 0.01 ) ) ;hoff das ist nicht ganz falsch
-
Ist doch klar, dass ein relativer Vergleich zu 0 immer fehl schlägt. Der relative Unterschied zwischen 0 und nicht-0 ist immer unendlich groß. Gerade deshalb sind Fließkommavergleiche doch so schwer: Legt man eine relative Toleranz fest, dann bekommt man Probleme, wenn ein winziger Unterschied zu einem großen relativen Unterschied führt. Legt man absolute Toleranzen fest, bekommt man Probleme, wenn die Zahlen kleiner werden als die Auslegung der Toleranz. Den Stein der Weisen gibt es da nicht. Siehe folgende Abhandlung:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
(Wobei da schon ein paar gute Vorschläge gemacht werden, auf die man alleine nicht so schnell kommt)Du suchst hier anscheinend einen absoluten Vergleich, so wie dein selbst gebastelter Vergleich. Das gibt's auch im Boost Test-Framework, unter BOOST_CHECK_SMALL.
-
SeppJ schrieb:
Du suchst hier anscheinend einen absoluten Vergleich, so wie dein selbst gebastelter Vergleich. Das gibt's auch im Boost Test-Framework, unter BOOST_CHECK_SMALL.
BOOST_CHECK_SMALL schaut gut aus, vielen Dank!
-
SeppJ schrieb:
Der relative Unterschied zwischen 0 und nicht-0 ist immer unendlich groß.
und vielen Dank auch für das, auch wenns klar sein sollte, jetzt is es für mich klarer
-
SeppJ schrieb:
Ist doch klar, dass ein relativer Vergleich zu 0 immer fehl schlägt. Der relative Unterschied zwischen 0 und nicht-0 ist immer unendlich groß.
Ich hab da mal grad eine verwandte aber etwas andere Frage zu:
Was du da ansprichst ist ja auch als relative Abweichung bekannt. Die Formel dafür ist ja gleich, aber die Werte werden leicht anders interpretiert:
wobei:
die relative Abweichung
der reale (Mess-)Wert
der Ziel- oder Vergleichswert sei.Die relative Abweichung zu Werten ist ja simpel damit zu berechnen. Aber was mache ich/macht man, wenn der Sollwert 0 ist? Und wie ist das interpretierbar?
-
Ich glaube, da ist irgendwie die Hälfte deiner Frage verloren gegangen.
-
Nee -.-
Hab auf Vorschau mittendrin klicken wollen, war aber absenden. Ist jetzt vollständig.
-
Ich verstehe nicht ganz, was hier 0 sein soll. Beide? In dem Fall käme ein undefiniertes Ergebnis raus. Aber wenn man einen Sollwert 0 hat, ist es ohnehin Unsinn, mit einer relativen Abweichung zu rechnen, da jedes Ergebnis, das nicht 0 ist, eine unendlich große Abweichung hat. In dem Fall möchte man tatsächlich einen direkten Vergleich mit 0 (also mit == vergleichen).
-
Mir gehts grad weniger um den Vergleich, sondern um die wirkliche relative Abweichung.
Nehmen wir an ich habe eine Kostenfunktion für die Kanten eines Graphen c(x).
Und ich will eine Schätzfunktion h(x) für diese Kosten bewerten. (z.B. damit ich weiss wie gut eine Heuristik für etwa A* ist)Dann kenne ich einmal das tatsächliche Ergebnis, also den Wert an einer Stelle und einmal den Schätzwert an der Stelle. Ich will jetzt wissen, wie gut mein Schätzwert ist - anhand der relativen Abweichung.
->
Soweit so gut, gefällt mir auch alles.
Das Problem ist nur, was passiert wenn es keine Kosten mehr gibt ()? Denn dann ist, egal was geschätzt wird, eine Division durch 0 vorhanden.Meine Frage ist: Wie geht man mit solch einer Situation um?
Ich meine, gerade in der Messtechnik, wo man diese Formal öfters benutzt, wird man hier und damal doch auch sicherlich als Ergebnis 0 erwarten, und das wäre ja dann auch ein Division-by-Zero "Fehler".
Bisher nutze ich in dem Fall die absolute Abweichung.