У меня есть программа, и я пытаюсь рассчитатьcos(M_PI*3/2)
и вместо получения 0, как я должен, я получаю -1.83691e-016
Что мне здесь не хватает? Я в радианах, как мне нужно быть.
Во-первых, M_PI — не очень переносимый макрос, и обычно он составляет около 15 десятичных знаков, в зависимости от того, какой компилятор вы используете. Полагаю, вы используете компилятор Microsoft C ++.
Во-вторых, если вам нужна более точная (и переносимая) версия, используйте библиотеку Boost Math:
http://www.boost.org/doc/libs/1_55_0/libs/math/doc/html/math_toolkit/tutorial/non_templ.html
В-третьих, как указал Кей, число пи по своей сути является иррациональным числом, и, следовательно, никакого количества бит (или цифр в базе 10) будет недостаточно для его точного представления. Следовательно, то, что вы на самом деле рассчитываете, это не cos (3 * pi / 2), а «косинус в 3/2 кратного приближения числа pi к требуемым битам», что НЕ будет 3 * pi / 2 и поэтому не будет ноль.
Наконец, если вы хотите настраивать точность для ваших математических констант, прочитайте это: http://www.boost.org/doc/libs/1_55_0/libs/math/doc/html/math_toolkit/tutorial/user_def.html
Число M_PI
является только приближением π. Косинус, который вы получаете, также является приблизительным, и он довольно хороший — он имеет пятнадцать правильных цифр после десятичной точки.
Учитывая дискретную природу double
значения, стандартная погрешность для проверки на числовое равенство numeric_limits<double>::epsilon()
:
#include <iostream>
#include <limits>
#include <cmath>
using namespace std;
int main()
{
double x = cos(M_PI*3/2);
cout << "x = << " << x << endl;
cout << "numeric_limits<double>::epsilon() = "<< numeric_limits<double>::epsilon() << endl;
cout << "Is x sufficiently close to 0? "<< (abs(x) < numeric_limits<double>::epsilon() ? "yes" : "no") << endl;
return 0;
}
Выход:
x = << -1.83697e-16
numeric_limits<double>::epsilon() = 2.22045e-16
Is x sufficiently close to 0? yes
Как видите, абсолютное значение -1.83697e-16
находится в пределах погрешности, заданной epsilon 2.22045e-16
,
Пи иррационально, компьютер не может точно представить число. Небольшая ошибка в «правильном» значении pi вызывает ошибку в выводе. Быть 1.83691 × 10-16 по-прежнему довольно хорошо.
Если вы хотите узнать больше об ограничениях реальной системы и влиянии небольших ошибок во входных данных, обратитесь к http://en.wikipedia.org/wiki/Numerical_stability.