【问题标题】:Sinus function using Taylor expansion使用泰勒展开的正弦函数
【发布时间】:2021-07-10 21:41:19
【问题描述】:

老师要求去掉main函数中的圆周率减法循环。我不知道如何编写程序,以便对任何值都得出正确的结果。

#include <stdio.h>

#include <math.h>

double sinus(double x);
int main(void) {
  double a, x;
  scanf("%le", & x);
  a = x;
  while (fabs(x) > 2 * (M_PI)) {
    x = fabs(x) - 2 * (M_PI);
  }
  if (a > 0)
    a = sinus(x);
  else a = (-1) * sinus(x);
  printf("%le", (double) a);
  return 0;
}

double sinus(double x) {
  double sum = 0, h, eps = 1.e-16;
  int i = 2;

  h = x;
  do {
    sum += h;
    h *= -((x * x) / (i * (i + 1)));
    i += 2;
  }
  while (fabs(h) > eps);
  return sum;
  return 0;
}

【问题讨论】:

  • 查找fmod 函数并使用它来代替循环。
  • 你能提供更多细节吗?
  • 请注意,将模运算放在sinus 函数中会更合乎逻辑。这可能是你老师关心的问题。

标签: c floating-point trigonometry taylor-series


【解决方案1】:
#include <stdio.h>
#include <math.h>
double sinus(double x);
int main(void)
{
    double a,x;
    scanf("%le",&x);
    a=x;
    x=fmod(fabs(x),2*(M_PI));
     if(a>0)
     a=sinus(x);
     else a=(-1)*sinus(x);
    printf("%le",(double)a);
    return 0;}
    
double sinus(double x)
{
  double sum=0, h, eps=1.e-16; int i=2;
 
h=x;
do{
    sum+=h;
    h*=-((x*x)/(i*(i+1)));
    i+=2;}
while( fabs(h)>eps );
return sum;
return 0;
}

【讨论】:

    【解决方案2】:

    ...如何编写程序,以便对任何值都得出正确的结果。

    OP 的循环很慢,x 很大,x 很大,无限循环:

    while (fabs(x) > 2 * (M_PI)) {
      x = fabs(x) - 2 * (M_PI);
    }
    

    简单,虽然不是高质量的解决方案,但在函数本身中使用fmod()@Damien:

    #ifndef M_PI
    #define M_PI 3.1415926535897932384626433832795
    #endif
    
    double sinus(double x) {
      x = fmod(x, 2*M_PI); // Reduce to [-2*M_PI ... 2*M_PI]
      ...
    

    虽然函数fmod() 预计不会注入任何error,但问题是M_PI(一个有理数)是π(一个无理数)的近似值。使用该值近似会注入误差,尤其是x 接近 π 的倍数。对于中等质量的代码,这可能是可以的。

    良好的范围缩减是一个与三角函数本身一样具有挑战性的问题。
    K.C. Ng's "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit"


    在尝试幂级数解决方案之前,OP 的 sinus() 应使用额外的范围缩减和三角函数来使 x 在范围 [-M_PI/4 ... M_PI/4] (example) 内。否则,收敛速度很慢,错误会累积。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-19
      • 2017-12-02
      • 2014-02-17
      • 2017-04-02
      • 1970-01-01
      • 2017-06-14
      • 2013-10-09
      相关资源
      最近更新 更多