Интересно, как калькуляторы работают с точностью. Например, значение sin(M_PI)
не является точно нулевым при вычислениях в double
точность:
#include <math.h>
#include <stdio.h>
int main() {
double x = sin(M_PI);
printf("%.20f\n", x); // 0.00000000000000012246
return 0;
}
Теперь я, конечно, хотел бы распечатать нуль, когда пользователь вводит sin(π). Я могу легко круглый где-нибудь на 1e–15 для создания этой конкретной патронажной работы, но это - взлом, не решение. Когда я запускаю к раунду как это, и пользователь вводит что-то как 1e–20, они возвращают нуль (из-за округления). То же самое происходит, когда пользователь вводит 1/10 и совершает нападки = ключ неоднократно — когда он достигает округления treshold, он получает нуль.
И все же некоторые калькуляторы возвращают простой нуль для sin(π), и в то же время, они могут работать с выражениями, такими как (1e–20)/10 удобно. Где прием?
Настольные калькуляторы используют математические библиотеки произвольной точности. Их можно настроить так, чтобы они имели гораздо более высокую точность, чем удвоение. В портативных калькуляторах (традиционных и мобильных) используются математические библиотеки с фиксированной точностью.
Если вы хотите напечатать ровно ноль, используйте спецификатор ширины
printf (%12.4d, number);
Они могут использовать справочную таблицу для ускорения своих триггерных формул. В этом случае специальные числа, которые хорошо работают, вероятно, просто были бы в таблице.
Некоторые ответы можно найти на странице Точность калькулятора .
Среди решений:
Уловка, вероятно, как уже говорилось, в том, что калькуляторы будут использовать математические библиотеки произвольной точности или таблицы поиска .
Я бы также добавил, что ваш фрагмент кода работает именно так из-за использования арифметики с плавающей запятой , что, как вы, вероятно, знаете, не истинная математика в том смысле, что она неточна - 1.0 + 0.1! = 1.1
(на самом деле это 1.1000000000000001) :)