繁体   English   中英

C ++:余弦是错的,应该是零。 3PI / 2

[英]C++: Cosine is wrong, should be zero. 3Pi/2

我有一个程序,我正在尝试计算cos(M_PI*3/2) ,而不是得到0,因为我应该,我得到-1.83691e-016

我在这里错过了什么? 我需要的是弧度。

数字M_PI仅是π的近似值。 你得到的余弦也是一个近似值,它是一个相当不错的余弦 - 它在小数点后面有十五个正确的数字。

首先,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

第三,正如凯指出的那样,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

鉴于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是不合理的,计算机无法完美地代表数字。 pi的“正确”值的小误差导致输出中的错误。 作为1.83691×10 -16关闭还是蛮不错的。

如果您想了解更多有关实际系统的限制以及输入中的小错误的影响,请参阅http://en.wikipedia.org/wiki/Numerical_stability

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM