double — C ++: косинус неправильный, должен быть равен нулю. 3PI / 2

У меня есть программа, и я пытаюсь рассчитатьcos(M_PI*3/2) и вместо получения 0, как я должен, я получаю -1.83691e-016

Что мне здесь не хватает? Я в радианах, как мне нужно быть.

2

Решение

Во-первых, 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

5

Другие решения

Число M_PI является только приближением π. Косинус, который вы получаете, также является приблизительным, и он довольно хороший — он имеет пятнадцать правильных цифр после десятичной точки.

5

Учитывая дискретную природу 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,

4

Пи иррационально, компьютер не может точно представить число. Небольшая ошибка в «правильном» значении pi вызывает ошибку в выводе. Быть 1.83691 × 10-16 по-прежнему довольно хорошо.

Если вы хотите узнать больше об ограничениях реальной системы и влиянии небольших ошибок во входных данных, обратитесь к http://en.wikipedia.org/wiki/Numerical_stability.

2