【问题标题】:Calculating sin(x) with Taylor series用泰勒级数计算 sin(x)
【发布时间】:2021-04-16 17:10:01
【问题描述】:

任务:根据 sin(x) 的泰勒级数计算,使用名为 mysin 的 double 函数将其传递给 double 变量。从用户那里取一个 x 值并使用 mysin 函数计算 sin(x)。

问题是程序给了我错误的 sin(x) 值。我一直试图解决这个问题大约 4 个小时,但找不到。是因为 sin(x) 函数还是我在代码中遗漏了什么?

我的代码:

#include <stdio.h>

double mysin(double x)
{
    double value = x;
    double sum = x;
    int neg_pos = 1;
    int fac = 1;
    
    int counter = 0;
    
    while(1)
    {
        neg_pos *= -1;
        fac += 2;
        
        value = value/(fac*(fac-1));
        value = value*x*x*neg_pos;

        sum += value;
        
        //printf("Hello");
        counter++;
        if (counter == 100) break;
    }
    return sum;
}

int main()
{
    double number;
    scanf("%lf",&number);
    printf("%g",mysin(number));
    //printf("%g",number);
}

【问题讨论】:

  • 问题是程序给了我错误的 sin(x) 值。我一直试图解决这个问题大约 4 个小时,但找不到。是因为 sin(x) 函数还是我的代码中遗漏了什么?
  • 我不小心把questin放在了代码的底部。对不起:(
  • 那个阶乘累加看起来....错了。
  • 您是否尝试过使用调试器在监视变量及其值的同时逐句执行代码?在计算中的任何错误变得清晰之前不需要多次迭代。

标签: c math formula


【解决方案1】:

问题是你每一步都乘以neg_pos,它在+1和-1之间切换。这意味着术语只有一半的时间改变符号,而它们每次都应该改变符号。

解决方法是每次只乘以 -1 而不是 neg_pos

这是您的程序的一个工作的、稍微简化的形式,它计算从 0 到 3 的数字范围的 sin,显示要比较的 stdlib 计算。

#include <math.h>
#include <stdio.h>

double mysin(double x) {
    double value = x;
    double sum = x;
    int fac = 1;
    
    for (int counter = 0; counter < 100; counter++) {
        fac += 2;
        value = -value*x*x/fac/(fac-1);
        sum += value;
    }
    return sum;
}

int main() {
    for (double x = 0.0; x < 3.0; x += 0.1) {
       printf("%g: %g %g\n", x, mysin(x), sin(x));
    }
}

您也可以避免使用单独的 faccounter 变量,可能是这样:

double mysin(double x) {
    double term=x, sum=x;
    for (int f = 0; f < 100; f++) {
        term = -term*x*x/(2*f+2)/(2*f+3);
        sum += term;
    }
    return sum;
}

【讨论】:

  • 当我将所有 neg_pos 转换为注释行并添加“-”时,它工作正常。但这没有任何意义。为什么变量不起作用而“-”起作用? “这意味着条款只有一半时间改变符号”怎么可能?
  • neg_pos 在 +1 和 -1 之间交替,因此您将前一项乘以 +1 的一半时间和 -1 的一半时间。但是泰勒级数中的术语总是与之前的术语有不同的符号。
  • 我认为您正在考虑乘以 neg_pos 来设置表达式的符号,但只有当您乘以它是正数时,这才是正确的。您可以尝试打印出这些术语,并将它们与-1^n*x^n/n! 的真实值进行比较。
【解决方案2】:

据我了解,您没有正确计算功率 首先使用这个:

#include <math.h>

然后创建一个阶乘函数:

int factorial(int x){
   int result = 1;
   for(int i = 1; i < x; i++){
      result += result * i;
   }
   return result;
}

最后:

while(1)
 {
    neg_pos *= -1;
    fac += 2;
    
    power = pow(x,fac);
    fac = factorial(fac);

    sum += power/fac;
    
    //printf("Hello");
    counter++;
    if (counter == 100) break;
}

【讨论】:

  • 问题的作者试图计算中间项,而不是每次都重新计算阶乘。计算 x^fac 和 fac!分别产生巨大的数字,然后将其划分为非常小的数字。它们太大了,导致溢出。还是13!溢出 32 位 int,并且您的代码尝试计算 200!。 200!有 375 位,甚至比最大的 double 值还要大。
  • 你有一个奇怪的阶乘实现。这是正确的,但看起来是错误的,因为循环显然是一对一的,并且在计算中有一个 +=。但它有效,因为r += r*i 等同于r = r * (i + 1)。不知道你是怎么写成这样的!
  • 是的,我没有意识到这一点。每次计算阶乘是非常昂贵的。连续存储它的值并从中计算它要聪明得多!
猜你喜欢
  • 2016-06-04
  • 2018-06-23
  • 2020-03-01
  • 2021-08-13
  • 2021-03-19
  • 2014-03-27
  • 2015-05-15
  • 1970-01-01
  • 2016-04-26
相关资源
最近更新 更多