在C ++中计算arctan(x)的值

时间:2013-05-03 05:29:10

标签: c++

我必须计算arctan(x)的值。我通过评估以下系列计算了这个值:

  

Arctan(x)= x - x ^ 3/3 + x ^ 5/5 - x ^ 7/7 + x ^ 9/9 - ...

但是下面的代码无法计算实际值。例如,calculate_angle(1)返回38.34。为什么?

const double DEGREES_PER_RADIAN = 57.296;

double calculate_angle(double x)
{
    int power=5,count=3;
    double term,result,prev_res;

    prev_res = x;
    result= x-pow(x,3)/3;

    while(abs(result-prev_res)<1e-10)
    {
        term = pow(x,power)/power;
        if(count%2==0)
            term = term*(-1);
        prev_res=result;
        result=result+term;
        ++count;
        power+=2;
       // if(count=99)
         //   break;
    }

    return result*DEGREES_PER_RADIAN;
}

3 个答案:

答案 0 :(得分:3)

编辑:我找到了罪魁祸首。您忘记包含stdlib.h功能abs所在的位置。您必须忽略有关隐式声明abs的警告。我检查了删除include会产生结果38.19并包含它会产生结果~45。

当使用未声明的函数(在本例中为abs)时,编译器不需要停止编译。相反,它允许对函数的声明方式做出假设(在这种情况下,是错误的。)

此外,与其他已经说过的海报一样,你使用abs是不合适的,因为它返回一个int,而不是double或float。 while中的条件应为>1e-100而不是<1e-1001e-100也太小了。

-

在计算前两个加数后,您忘记增加countpower

prev_res = x;
result= x-pow(x,3)/3;

count = 4; <<<<<<
power = 5; <<<<<<

while(abs(result-prev_res)<1e-100)
{
    term = pow(x,power)/power;
    if(count%2==1)
        term = term*(-1);

此外,我考虑使用count变量违反直觉:它与3初始化,如果它表示最后使用的权力;但是,循环迭代会将其增加1而不是2,您可以按count%2 == 1而不是power%4 == 3来确定符号

答案 1 :(得分:3)

该系列会聚到tan ^ { - 1} x,但速度不是很快。在x=1

时考虑系列
1 - 1/3 + 1/5 - 1/7 + 1/9 - ...

1/9期间截断时出现的错误是什么?它在1/9左右。要获得10^{-100}准确度,您需要10^{100}个术语。宇宙会在你得到它之前结束。并且,灾难性的舍入错误和截断错误会使答案完全不可靠。 double s只能使用14位数字。

查看Abramowitz和Stegun [AMS 55]的参考文献或http://dlmf.nist.gov的新NIST数学函数数字图书馆,看看这些是如何在实践中完成的。通常,人们使用Padé近似而不是Taylor系列。即使你坚持使用泰勒系列,你也经常使用切比雪夫近似来减少总误差。

我还推荐Forman Acton的[通常]工作的数值方法。或者......系列中的数字食谱。

答案 2 :(得分:2)

在前两个学期之后你的签名是错误的。它应该是:

if(count%2==0)
  term = term*(-1);

在while条件下你的比较是错误的。而且,你期望一种不切实际的高精度。我会建议更像这样的东西:

while(fabs(result-prev_res)>1e-8)

最后,您将获得更准确的结果,并为DEGREES_PER_RADIAN提供更好的价值。为什么不这样:

const double DEGREES_PER_RADIAN = 180/M_PI;