我每隔几个月偶然发现一个错误是这个:
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
}
您会假设代码显示“x 等于 y”,但事实并非如此。
简短的解释是小数位表示为二进制数字,不适合双精度数。
示例:2.625 看起来像:
10.101
因为
1-------0-------1---------0----------1
1 * 2 + 0 * 1 + 1 * 0.5 + 0 * 0.25 + 1 * 0,125 = 2.65
并且某些值(例如 19.08 加上 2.01 的结果)不能用双精度位表示。
一种解决方案是使用常量:
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!");
}
如果我在第一个示例中使用十进制而不是双精度,则结果是“x 等于 y”。
但我在问自己这是不是因为“十进制”类型不容易受到这种行为的影响,或者它只是在这种情况下起作用,因为值“适合”到 128 位。
也许有人有比使用常量更好的解决方案?
顺便提一句。这不是 dotNet/C# 问题,它发生在我认为的大多数编程语言中。