Ответ 1
Вероятно, он оптимизирован до (0,3!= 0,3). Это, очевидно, ложно. Проверьте настройки оптимизации, убедитесь, что они выключены, и повторите попытку.
assert(0.1 + 0.2 != 0.3); // shall be true
- моя любимая проверка того, что язык использует собственную арифметику с плавающей запятой.
#include <cstdio>
int main()
{
printf("%d\n", (0.1 + 0.2 != 0.3));
return 0;
}
Вывод:
1
print(0.1 + 0.2 != 0.3)
Вывод:
True
Почему это не так для D? Понятно, что D использует собственные числа с плавающей запятой. Это ошибка? Используют ли они какое-то определенное числовое представление? Что-то другое? Довольно запутанный.
import std.stdio;
void main()
{
writeln(0.1 + 0.2 != 0.3);
}
Вывод:
false
Благодаря LukeH. Это эффект Floating Point Constant Folding, описанный там.
код:
import std.stdio;
void main()
{
writeln(0.1 + 0.2 != 0.3); // constant folding is done in real precision
auto a = 0.1;
auto b = 0.2;
writeln(a + b != 0.3); // standard calculation in double precision
}
Вывод:
false
true
Вероятно, он оптимизирован до (0,3!= 0,3). Это, очевидно, ложно. Проверьте настройки оптимизации, убедитесь, что они выключены, и повторите попытку.
(Ответ Flynn - правильный ответ. В этом случае проблема решается чаще).
Похоже, вы предполагаете, OP, что неточность с плавающей запятой в вашем коде детерминирована и предсказуема неправильно (в некотором смысле, ваш подход является полярным, противоположным тому, который не понимает с плавающей точкой).
Хотя (как указывает Бен), неточность с плавающей запятой является детерминированной, с точки зрения вашего кода, если вы не очень преднамеренно о том, что происходит с вашими значениями на каждом шагу, это не так. Любое количество факторов может привести к следующему 0.1 + 0.2 == 0.3
, оптимизация времени компиляции - это одно, повышенные значения для тех литералов, которые являются другими.
Не надейтесь здесь ни на успех, ни на неудачу; не полагайтесь на равенство с плавающей запятой в любом случае.
Согласно моей интерпретации спецификации языка D, арифметика с плавающей запятой на x86 будет использовать внутри себя 80 бит точности, а не только 64 бита.
Однако нужно было бы проверить, что этого достаточно, чтобы объяснить результат, который вы наблюдаете.