我必须用Taylor系列计算sin(x),直到输出有6位小数。争论是一个角度。我没有实现检查小数位,我只是打印下一个值(检查它是否正常工作),但是在10-20次迭代后它显示无穷大/ NaN&#39。 / p>
我的想法出了什么问题?
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);
}
}
等式:
答案 0 :(得分: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;
}
答案 1 :(得分:0)
要添加@Xoce(和@FredK)提供的答案,请记住您正在计算McLaurin系列(关于x = 0
的Taylor的特例)。虽然这对于大约pi/2
零的值会相当快地收敛,但是在因子x
的因子爆炸之前,你可能无法收到数字的收敛。
我的建议是使用实际的泰勒级数来确定已知精确值的sin(x)
的最接近值(即pi/2
的最接近的倍数,而不仅仅是零。收敛检查!
答案 2 :(得分:-1)
NAN错误通常是一个非常大的数字,如果你划分2个数字但除数非常小或为零,就会发生这种情况。
这是因为你的阶乘数正在溢出,后来在某些时候你再次除以零
如果将factorial作为参数作为int,则通过例如BIgInterger
对象进行更改。