泰勒级数 - 计算 sin(x) 直到 6 位精度

Taylor series - calculating sin(x) until 6 digits precision

我必须用泰勒级数计算 sin(x),直到输出有 6 位小数。参数是一个角度。我没有实现检查小数位,我只是打印下一个值(以检查它是否有效),但在 10-20 次迭代后它显示 infinities/NaN。

我的想法有什么问题吗?

public static void sin(double x){
    double sin = 0;
    int n=1;
    while(1<2){

        sin += (Math.pow(-1,n) / factorial(2*n+1)) * Math.pow(x, 2*n+1);
        n++;

        try {
            Thread.sleep(50);
        } catch (InterruptedException ex) {

        }

        // CHECKING THE PRECISION HERE LATER
        System.out.println(sin);
    }
}

等式:

问题:

NAN 错误通常是一个非常大的数字,如果您将 2 个数字相除但除数很小或为零,就会发生这种情况。

解决方案

发生这种情况是因为你的阶乘数溢出了,后来在某个时候你又被零除了 如果您的阶乘被作为 int 参数,则将其更改为 BIgInterger 对象。

不要使用阶乘和幂来计算每一项!你会迅速溢出。 只需意识到下一项是 -term * x * x / ((n+1)*(n+2)) ,其中 n 每一项增加 2:

double tolerance = 0.0000007; // or whatever limit you want
double sin = 0.;
int n = 1;
double term = x;
while ( Math.abs(term) > tolerance ) {
  sin += term;
  term *= -( (x/(n+1)) * (x/(n+2)) );
  n+= 2;
}

要补充@Xoce(和@FredK)提供的答案,请记住您正在计算麦克劳林级数(泰勒的特例 x = 0)。虽然这对于零的 pi/2 范围内的值会相当快地收敛,但对于 x 更远的值,您可能无法在阶乘爆炸之前收敛数字。

我的建议是使用关于 sin(x) 的最接近值的实际泰勒级数,其确切值已知(即,最接近 pi/2 的倍数,而不仅仅是零。并且一定要做收敛检查!