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 du FLT_EPSILON, definiert in <float.h> oder <cfloat>?
  • Er erwähnt, dass er eine Garantie, dass a und b 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 oder false. 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 es Infinity 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ür NaNs).

InformationsquelleAutor Anne Quinn | 2013-03-12
Schreibe einen Kommentar