Wenn Sie Gleitkommazahlen verwenden, haben die relationalen Operatoren Bedeutungen, aber ihre Bedeutungen stimmen nicht unbedingt mit den tatsächlichen Zahlen überein.
Wenn Gleitkommawerte verwendet werden, um tatsächliche Zahlen (ihren normalen Zweck) darstellen, neigen die Operatoren verhalten sich wie folgt:
x > y
und x >= y
sowohl bedeuten, dass die numerische Größe, die x
soll repräsentieren ist wahrscheinlich größer als y
, und im schlimmsten Fall wahrscheinlich nicht viel weniger als y
.
x < y
und x <= y
beide implizieren, dass die numerische Größe, die x
sollte wahrscheinlich weniger vertreten als als y
, und ist im schlimmsten Fall wahrscheinlich nicht viel größer als y
.
x == y
bedeutet, dass die numerischen Größen, die x
und y
nicht zu unterscheiden sind voneinander
Hinweis dar, dass, wenn x
von float
Typ ist und y
ist vom Typ double
, werden die oben genannten Bedeutungen erreicht werden Wenn das double
Argument in float
umgewandelt wird. In Abwesenheit einer spezifischen Umwandlung werden jedoch C und C++ (und auch viele andere Sprachen) einen float
Operanden in double
konvertieren, bevor ein Vergleich durchgeführt wird. Eine solche Umwandlung wird die Wahrscheinlichkeit, dass die Operanden als "nicht unterscheidbar" gemeldet werden, stark verringern, wird aber die Wahrscheinlichkeit, dass der Vergleich ein Ergebnis ergibt, das zu dem, was die beabsichtigten Zahlen tatsächlich anzeigen, stark erhöht. Betrachten wir zum Beispiel
float f = 16777217;
double d = 16777216.5;
Wenn beide Operanden zu float
gegossen werden, wird der Vergleich zeigen, dass die Werte nicht zu unterscheiden sind. Wenn sie in double
umgewandelt werden, zeigt der Vergleich an, dass d
größer ist, obwohl der Wert f
etwas größer darstellen soll. Als extremes Beispiel:
float f = 1E20f;
float f2 = f*f;
double d = 1E150;
double d2 = d*d;
Float f2
enthält die beste float
Darstellung von 1E40. Double d2
enthält die besten double
darstellung von 1E400. Die numerische Menge, dargestellt durch d2 is hundreds of orders of magnitude greater than that represented by
f2 , but
(doppelt) f2> d2 . By contrast, converting both operands to float would yield
f2 == (Gleitkomma) d2 ', korrekte Meldung, dass die Werte nicht unterscheidbar sind.
PS - Ich bin mir durchaus bewusst, dass IEEE-Standards erfordern, dass Berechnungen Fließkommawerte stellen genaue Potenz von zwei Fraktionen, als ob durchgeführt werden, aber nur wenige Menschen den Code float f2 = f1/10.0;
als „Set f2 auf die darstellbare Leistung sehen -von-zwei-Bruch, der am nächsten ist, ein Zehntel von dem in f1 zu sein ". Der Zweck des Codes besteht darin, f2 zu einem Zehntel von f1 zu machen. Aufgrund von Ungenauigkeit kann der Code diesen Zweck nicht perfekt erfüllen, aber in den meisten Fällen ist es hilfreicher, Gleitkommazahlen als tatsächliche numerische Größen zu betrachten, als sie als Zweier-Potenz zu betrachten.
Es gibt nichts falsch mit Gleichheit-vergleichen Gleitkommawerte per se. Das Problem ist, dass sich das Ergebnis möglicherweise nicht wie erwartet verhält. –