Ein Fehler, den ich auf alle paar Monate stolpern ist diese:Ist der dotNet-Dezimaltyp anfällig für den binären Vergleichsfehler?
double x = 19.08;
double y = 2.01;
double result = 21.09;
if (x + y == result)
{
MessageBox.Show("x equals y");
}
else
{
MessageBox.Show("that shouldn't happen!"); // <-- this code fires
}
Sie den Code annehmen würde, um „x gleich y“, aber das ist nicht der Fall.
Die kurze Erklärung ist, dass die Dezimalstellen, dargestellt als eine Binärziffer, nicht in das Doppelte passen.
Beispiel: 2.625 würde wie folgt aussehen:
10,101
weil
1-------0-------1---------0----------1
1 * 2 + 0 * 1 + 1 * 0.5 + 0 * 0.25 + 1 * 0,125 = 2.65
Und einige Werte (wie das Ergebnis von 19,08 und 2,01) nicht mit den Bits a dargestellt werden, werden doppelt.
Eine Lösung ist eine Konstante zu verwenden:
double x = 19.08;
double y = 2.01;
double result = 21.09;
double EPSILON = 10E-10;
if (x + y - result < EPSILON)
{
MessageBox.Show("x equals y"); // <-- this code fires
}
else
{
MessageBox.Show("that shouldn't happen!");
}
Wenn ich dezimal anstelle von Doppel im ersten Beispiel, ist das Ergebnis „x y gleich“.
Aber ich frage mich, ob dies wegen "dezimal" Typ ist nicht anfällig für dieses Verhalten oder es funktioniert einfach in diesem Fall, weil die Werte in 128 Bit "passen".
Vielleicht hat jemand eine bessere Lösung als die Verwendung einer Konstante?
Btw. Dies ist kein dotNet/C# -Problem, es passiert in den meisten Programmiersprachen, denke ich.
Es ist sicher http://docs.sun.com/source/806-3568/ncg_goldberg.html ist ein berühmtes Papier. – RichardOD