Floating Point, wie viel kann ich Vertrauen, kleiner als / größer als-Vergleiche?
Sagen wir, ich habe zwei floating-point-zahlen, und ich will um Sie zu vergleichen. Wenn einer größer ist als der andere, sollte das Programm nehmen Sie eine Gabel. Wenn das Gegenteil wahr ist, es sollte einen anderen Weg nehmen. Und es sollte das gleiche tun, wenn der Wert, der verglichen wird ist touchierte ganz leicht in eine Richtung, sollte es immer noch machen vergleichen wahr.
Es ist eine schwierige Frage zu Satz, so dass ich schrieb, dies zu demonstrieren, it -
float a = random();
float b = random(); //always returns a number (no infinity or NaNs)
if(a < b){
if( !(a < b + FLOAT_EPISILON) ) launchTheMissiles();
buildHospitals();
}else if(a >= b){
if( !(a >= b - FLOAT_EPISILON) ) launchTheMissiles();
buildOrphanages();
}else{
launchTheMissiles(); //This should never be called, in any branch
}
Angesichts dieser code ist launchTheMissiles()
garantiert nie aufgerufen werden?
- docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
- Ich sehe keine Garantie, dass
b + FLOAT_EPISILON
ist nicht unendlich, die kann dazu führen, Raketen. - Was ist
FLOAT_EPISILON
? Meinst duFLT_EPSILON
, definiert in<float.h>
oder<cfloat>
? - Er erwähnt, dass er eine Garantie, dass
a
undb
sind beide nicht NaN und nicht-Infinity-oder -Inf. - Es ist schlechter Stil, und manchmal gefährlich, zu vergleichen boolescher Werte auf Gleichheit zu
true
oderfalse
.x > y
ist schon eine Bedingung. Wenn Sie möchten, um Sie zu negieren, verwenden Sie die!
Betreiber. - Wenn
b
ist so nah an der maximal Darstellbare float -, dass+ FLOAT_EPISILON
dazu, dass es größer ist als es und überlauf, wird esInfinity
und das wird zu Problemen führen. Ähnlich wie für negative Unendlichkeit. Ansonsten sind Sie in Ordnung. - geändert Vergleiche
- Unter der Annahme, dass die eigentlich
FLT_EPSILON
Hinzugefügt, dass Wert auf eine sehr große Zahl wird wahrscheinlich ergeben die gleiche Zahl. Ich glaube es ist nicht garantiert, obwohl; in der Theorie, es könnte überlaufen. (Und ich glaube nicht, dass es eine Garantie, dass ein überlauf ergibt Unendlich.) - Thompson Du hast Recht, es ist schwer zu überlauf durch addition 🙂 >>> sys.float_info.max+sys.float_info.max/100000000000000000 1.7976931348623157 e+308 >>> sys.float_info.max+sys.float_info.max/10000000000000000 inf
- Sie wurden betrogen von den "immer zu vergleichen, schwimmt mit epsilon"-Müll herum, aber Nein,
launchTheMissles
können nie aufgerufen werden (gut, außer fürNaN
s).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie garantieren können, dass
a
undb
sind keine NaNs oder unendlichen, dann können Sie nur:Alle floating-point-Werte außer für Ewigkeiten und NaNs umfassen eine Gesamt Bestellung (mit einem glitch mit zwei Darstellungen der null, aber das sollte keine Rolle für Sie), die nicht im Gegensatz zu arbeiten mit normaler Menge der ganzen zahlen — der einzige Unterschied ist, dass die Größe der Intervalle zwischen den nachfolgenden Werten nicht konstant ist, wie es ist, mit ganzen zahlen.
In der Tat, die IEEE 754 wurde so konzipiert, dass Vergleiche von nicht-NaN non-infinity-Werte die gleichen Zeichen mit den gleichen Operationen, wie normale ganze zahlen (wieder, mit einem glitch mit null). Also, in diesem spezifischen Fall haben, können Sie denken, diese zahlen als "besser " Ganzzahlen".
Kurze Antwort, es ist garantiert nie aufgerufen werden.
Wenn
a<b
dann ein immer kleiner als b sowie einen positiven Betrag jedoch kleiner. In dem Fall testen wenn a kleiner als b + ein Betrag wird wahr.Dritten Fall wird nicht erhalten, erreicht.
Tests für Ungleichheit sind genau, wie sind die tests für die Gleichheit. Menschen sind verwirrt, weil Sie nicht erkennen, dass die Werte, mit denen Sie arbeiten vielleicht nicht genau das, was Sie denken, Sie sind. Also, ja, der Kommentar auf die Letzte Funktion aufrufen, korrekt ist. Dieser Zweig wird nie genommen werden.
FLT_EPSILON
hat nichts mit diesem zu tun; es ist einfach der kleinste Wert, der Hinzugefügt werden kann1.0f
zu produzieren, die einen unterschiedlichen Wert, d.h., es gibt Ihnen Informationen über die zugrunde liegenden Repräsentation.IEEE 754 (floating point) standard besagt, dass die addition oder Subtraktion kann in einem positiven oder negativen unendlich, also b + FLOAT_EPSILON und b - FLOAT_EPSILON kann das Ergebnis positiv oder negativ unendlich, wenn b ist FLT_MAX oder -FLT_MAX. Die floating-point-standard auch fest, dass die Unendlichkeit vergleicht, wie man es erwarten würde, mit FLT_MAX < +unendlich "true" zurückgeben und -FLT_MAX > -die Unendlichkeit.
Für einen genaueren Blick auf die floating-point-format und precision-Probleme aus praktischer Sicht, ich empfehle einen Blick auf Christer Ericson Buch Real-Time Collision Detection oder Bruce Dawson ' s blog-posts zum Thema, das neueste (mit einem tollen Inhaltsverzeichnis!) ist bei http://randomascii.wordpress.com/2013/02/07/float-precision-revisited-nine-digit-float-portability/.
x
undy
sind echte numerische Mengenxf
ist die bestefloat
Darstellungx
, undyd
ist die bestedouble
Darstellungy
,xf > (float)yd
wird nur wahr sein, wennx
ist entweder größer alsy
oder sehr, um es zu schließen (innerhalb von einer halben LSB einesdouble
), aber(double)xf > yd
mag wahr sein, auch wenny
Hunderte von Größenordnungen größer ist alsx
.Was weniger als vorher mit einem epsilon-Fenster ? wenn a kleiner als b kann a nicht gleich b