Java中的正弦近似误差
我对我在Java中编写的一个近似正弦函数的方法有点恼火。这是基于泰勒级数的Java中的正弦近似误差,java,math,trigonometry,Java,Math,Trigonometry,我对我在Java中编写的一个近似正弦函数的方法有点恼火。这是基于泰勒级数的 static double PI = 3.14159265358979323846; static double eps = 0.0000000000000000001; static void sin(double x) { x = x % (2 * PI); double term = 1.0; double res = 0.0; for (int i = 1; te
static double PI = 3.14159265358979323846;
static double eps = 0.0000000000000000001;
static void sin(double x) {
x = x % (2 * PI);
double term = 1.0;
double res = 0.0;
for (int i = 1; term > eps; i++) {
term = term * (x / i);
if (i % 4 == 1) res += term;
if (i % 4 == 3) res -= term;
}
System.out.println(sum);
}
对于较小的值,我得到了非常好的正弦近似值,但是对于较大的值(例如pow(10,22)),结果似乎非常错误
结果如下:
sin(pow(10,22)) // 0.8740280612007599
Math.sin(pow(10,22)) // -0.8522008497671888
有人有主意吗?谢谢大家!
向您致意,请放心,Java
sin
功能也将关闭
你的问题是sin
的泰勒展开有一个小的收敛半径,即使在这个半径内,收敛也很慢
还有浮点注意事项:浮点double
可提供大约15位有效精度
因此,对于sin
的大参数,精度将显著降低,特别是考虑到sin
是一个周期函数:
sin(x+2*pi*n)=sin(x)
对于任何整数n
对于大数字,您的答案是不正确的,因为您由于双精度
表示积累了大量舍入错误。当数字较大时,您的for
循环将在项
小于epsilon之前进行大量迭代。在每次迭代中,将累积舍入误差。结果是最终值的误差很大。阅读一些关于“数值分析”的很好的参考资料。无论如何,根据定义,泰勒级数接近于0。因此,对非常大的数字不正确是正常的。这种差异实际上与泰勒级数的收敛半径无关,而是与双精度有关,其精度不足以保持如此大的数字所需的精度。正弦函数的泰勒级数的半径为无穷大
10^22约为2^73。由于双精度数字的尾数为52位,因此可以使用双精度格式存储的连续值彼此之间的间隔为2^21。由于正弦函数的求值需要更多的分辨率,因此无法可靠地得到答案。我认为
x=x%(2*PI)
将避免这种精度损失(即使是参数的近似值)。有没有办法减少这个?没有。初始的x
将过于近似。不能对周期函数使用大浮点参数。恐怕这就是生活。好问题。我很惊讶没有人投票支持它。谢谢!我将寻找另一种方法(我和一些朋友正在学校写一种新的语言。我们必须实施一门数学课!)。如果您有任何有用的参考资料……)@芭丝谢芭为什么“准确度会显著下降,特别是考虑到罪恶是一个周期函数”?关于精度,周期函数有什么特别之处?因为随着浮点数变大,它们之间的“间隙”也会变大。