我有一个程序,我正在尝试计算cos(M_PI*3/2)
而不是得到0,我应该得到-1.83691e-016
我在这里缺少什么?我需要的是弧度。
答案 0 :(得分:5)
数字M_PI
只是π的近似值。你得到的余弦也是一个近似值,它是一个相当不错的余弦 - 它在小数点后面有十五个正确的数字。
答案 1 :(得分:5)
首先,M_PI不是一个非常便携的宏,并且通常对大约15个小数位有好处,这取决于你使用的编译器 - 我的猜测是你正在使用微软的C ++编译器。
其次,如果您想要更准确(和可移植)的版本,请使用Boost Math库: http://www.boost.org/doc/libs/1_55_0/libs/math/doc/html/math_toolkit/tutorial/non_templ.html
第三,正如Kay指出的那样,pi本身就是一个无理数,因此没有多少比特(或基数10中的数字)就足以准确地表示它。因此,你实际计算的不是cos(3 * pi / 2),而是“给定所需位的pi的最接近的近似值的3/2的余弦”,这不是3 * pi / 2和因此不会为零。
最后,如果您想要数学常量的自定义精度,请阅读:http://www.boost.org/doc/libs/1_55_0/libs/math/doc/html/math_toolkit/tutorial/user_def.html
答案 2 :(得分:4)
鉴于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
给出的误差范围内。
答案 3 :(得分:2)
如果您想了解更多有关实际系统的限制以及输入中的小错误的影响,请参阅http://en.wikipedia.org/wiki/Numerical_stability。