Одна ошибка, я наткнуться на каждые несколько месяцев это один:Является ли dotNet десятичным типом уязвимым для двоичной ошибки сравнения?
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
}
Вы бы предположить код для отображения «х равно у», но это не так.
Короткое объяснение состоит в том, что десятичные знаки, представленные в виде двоичной цифры, не вписываются в двойные.
Пример: 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!");
}
Если я использую десятичной вместо двойной в первом примере, результат «х равен у».
Но я спрашиваю себя, если это из-за «десятичного» типа, не уязвим для этого поведения или просто работает в этом случае, потому что значения «подходят» к 128 бит.
Возможно, у кого-то есть лучшее решение, чем использование константы?
КПП. это не проблема dotNet/C#, это происходит на большинстве языков программирования, я думаю.
Это, безусловно, http://docs.sun.com/source/806-3568/ncg_goldberg.html - известная статья. – RichardOD