2

我必须用泰勒级数计算 sin(x),直到输出有 6 个小数位。论据是一个角度。我没有实现检查小数位,我只是打印下一个值(以检查它是否工作),但在 10-20 次迭代后它显示无穷大/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);
    }
}

方程:

在此处输入图像描述

4

3 回答 3

2

不要使用阶乘和幂来计算每个项!你会迅速溢出。只需意识到下一项是 -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;
}
于 2016-02-22T18:34:33.330 回答
0

要补充@Xoce(和@FredK)提供的答案,请记住您正在计算 McLaurin 级数(Taylor about 的特殊情况x = 0)。虽然对于大约为零的值,这将很快pi/2收敛,但在阶乘爆炸之前,您可能无法获得数字的收敛x

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

于 2016-02-22T18:37:11.253 回答
-1

问题:

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

解决方案

发生这种情况是因为您的阶乘数溢出,并且稍后如果您的阶乘被用作 int 的参数,那么您将再次除以零,然后将其更改为,例如,一个BIgInterger对象。

于 2016-02-22T17:58:25.167 回答