变量的值不在循环中变化

时间:2016-03-16 15:32:36

标签: c math geometry sin

我有一个计算弧度角sin()的函数。它需要两个参数,弧度的角度值和术语。为了使一切清楚,这就是sin()的计算方法:

sin(x) = x - (1/3! * X^3) + (1/5! * X^5) - (1/7! * X^7) + (1/9! * X^9) - ...

这是执行此计算的函数:

double sinx(double theta, int terms) //Theta is the angle x in radian
{
  double result = 0;//this variable holds the value and it's updated with each term.
  int i = 1;
  int num = 3;

      while(i <= terms-1)
  {
           if(i % 2 != 0){
                result = result - ( (1.0/factorial(num)) * pow(theta, num) );
                printf("if\n");//this is just for debugging 
                }
             else if(i % 2 == 0){
                result = result + ( (1.0/factorial(num)) * pow(theta, num) );
                printf("else if\n");//this is for debugging too
                }
        printf("%lf\n", result);//debugging also

        num = num + 2;
        i = i + 1;
  }

      return theta + result; //this calculates the final term
}

问题是变量结果的值不会改变。当使用不同数量的术语时,这也导致最终结果不会改变。

这些是我得到的一些输出:

//with theta = 0.2 and terms = 6 ;;
if
-0.001333   
else if
-0.001331   
if
-0.001331   
else if
-0.001331   
if
-0.001331   
Computed Sin<0.200000> = 0.198669. //this is the returned value. It's printed in the main

//with theta = 0.2 and terms = 7
if
-0.001333   
else if
-0.001331   
if
-0.001331   
else if
-0.001331   
if
-0.001331   
else if
-0.001331   
Computed Sin<0.200000> = 0.198669. 

有什么想法吗?

5 个答案:

答案 0 :(得分:2)

您的代码应该是完全正确的。至少我的计算器给出了相同的结果。

如果您将printf("%lf\n", result);更改为printf("%.17f\n", result);,则会获得此输出:

if
-0.00133333333333333
else if
-0.00133066666666667
if
-0.00133066920634921
else if
-0.00133066920493827
if
-0.00133066920493878
else if
-0.00133066920493878

现在你可以看到,它在每个循环中仍在变化,但很少。

答案 1 :(得分:2)

它确实快速收敛,因此对于双精度而言,6到7项之间没有差异。这是具有更高精度的转储:

if

-0.00133333333333333350

else if

-0.00133066666666666680

if

-0.00133066920634920640

else if

-0.00133066920493827170

if

-0.00133066920493878470

Sin(0.2, 6) = 0.19866933079506122000
if

-0.00133333333333333350

else if

-0.00133066666666666680

if

-0.00133066920634920640

else if

-0.00133066920493827170

if

-0.00133066920493878470

else if

-0.00133066920493878450

Sin(0.2, 7) = 0.19866933079506122000

答案 2 :(得分:2)

这里的一切看起来都很正确。结果似乎没有变化的原因在于"window.zoomLevel": 1 的泰勒级数对于小角度的收敛速度。如果您尝试使用更大的数字sin,您应该会更频繁地看到值更新。您可能还希望包含一些内容以将theta从pi限制为-pi,因为sin是一个周期函数。

+pi

如果您开始计算值theta = mod(theta+pi, 2*pi) - pi > pi

,则包含此限制将减少对更多字词的需求

如果性能很重要,那么你可以通过在计算阶乘和大指数时删除重复来减少一些计算

< -pi

答案 3 :(得分:0)

如果您的factorial以正确的方式书写,您发布的程序似乎非常正确。我用这种方式写了因子:

double factorial(int n) {
    if(n <= 1) {
        return 1.0;
    }
    else {
        return n * factorial(n-1);
    }
}

尝试使用它。

使用0.785398(约pi/4)和10个术语,我得到输出0.707107

double d = sinx(0.785398, 10);
printf("%f\n", d); // prints 0.707107

以下是一些运行:

printf("%.20f\n", sinx(3.1415926535897932, 100));
printf("%.20f\n", sinx(3.1415926535897932/2, 100));
printf("%.20f\n", sinx(3.1415926535897932/4, 100));

输出:

0.00000000000000044409
1.00000000000000000000
0.70710678118654746000

这似乎足够准确,因为使用的pi只是近似值。

答案 4 :(得分:0)

你期待什么?

第三个词是

0.2^5/120 = 0.000002

如果显示前六位小数,则下一个小数字更小。

旁注

使用重现

计算以前的术语更有效,更准确
T*= Z/(N*(N-1))

其中Z= -X*X(这样,交替标志会自动处理)。