Почему 0,1 + 0,2 == 0,3 в D?
assert(0.1 + 0.2 != 0.3); // shall be true
моя любимая проверка, что язык использует собственную арифметику с плавающей точкой.
C++
#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 использует собственные числа с плавающей точкой. Это ошибка? Они используют какое-то конкретное представление чисел? Что-то другое? Довольно запутанно.
D
import std.stdio;
void main()
{
writeln(0.1 + 0.2 != 0.3);
}
Выход:
false
ОБНОВИТЬ
Благодаря LukeH. Это эффект сложения констант с плавающей точкой, описанный там.
Код:
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
3 ответа
Вероятно, он оптимизирован до (0,3!= 0,3). Что, очевидно, неверно. Проверьте настройки оптимизации, убедитесь, что они отключены, и попробуйте снова.
(Ответ Флинна - правильный ответ. Этот вопрос решает проблему в более общем плане.)
OP, вы, похоже, предполагаете, что неточность с плавающей запятой в вашем коде является детерминированной и предсказуемо неправильной (в некотором смысле, ваш подход является противоположностью подхода людей, которые еще не понимают с плавающей запятой).
Хотя (как указывает Бен) неточность с плавающей запятой является детерминированной, с точки зрения вашего кода, если вы не слишком продуманны в отношении того, что происходит с вашими значениями на каждом этапе, это не будет иметь место. Любое количество факторов может привести к 0.1 + 0.2 == 0.3
успешно, оптимизация во время компиляции - это одно, подправленные значения для этих литералов - другое.
Здесь не полагайтесь ни на успех, ни на неудачу; не полагайтесь на равенство с плавающей точкой в любом случае.
Согласно моей интерпретации спецификации языка D, арифметика с плавающей запятой в x86 будет использовать внутреннюю точность 80 бит, а не только 64 бита.
Однако следует проверить, что этого достаточно, чтобы объяснить результат, который вы наблюдаете.