我的Math.cos()
方法有点问题。我知道,我必须在使用之前将角度转换为弧度Math.cos()
。但如果我这样做:
System.out.println(Math.cos(Math.toRadians(90));
它输出:6.123233995736766E-17
Math.sin()
运作良好。
我的Math.cos()
方法有点问题。我知道,我必须在使用之前将角度转换为弧度Math.cos()
。但如果我这样做:
System.out.println(Math.cos(Math.toRadians(90));
它输出:6.123233995736766E-17
Math.sin()
运作良好。
从三角函数:
sin x ~= x, for small values of x
sin x = cos x+pi/2
因为 pi/2 不能在 IEEE-754 浮点中精确表示,这意味着它必须由某个值 x 表示,即它由 pi/2 +- x 表示,其中 x < 中的最低有效位浮点系统。在这种情况下是 2^-53 = 1.1102e-16。
在这种特殊情况下,x ~= 6.123233995736766E-17,大约是最大误差的 55%。所以,这是一个相当不错的结果......
请参阅 Javadoc。“从度数到弧度的转换通常是不精确的。”
该值非常接近正确结果。将度数转换为弧度的浮点运算似乎失去了精度。
暂时站在肥皂盒上,我认为人们对准确与精确的概念感到困惑。这是否像某些人所说的那样是一个问题?这是个问题吗?一个错误?或者它是浮点运算的预期行为?
90 度是一个可以完美表示为整数的数字,即使是双精度数。但是 pi/2 弧度是一个没有精确表示的实数,因此表示会稍微不准确。损失在于准确性。事实是,这是预期的行为。我们永远不应该相信结果中最不重要的部分。
接下来,当我们计算三角函数的值时,可能会有额外的精度损失。我们并没有得到我们知道在象征意义上是真实的结果。因此 sin(pi/3) 可能不完全是 sqrt(3)/2,但无论如何我们不能完全表示 sqrt(3)/2。所有这些都是意料之中的,并且是应该由好的代码处理的行为,而不是信任这些数字的 LSB。