Java Math.cos()方法在预期时不返回0
在Windows 7 PC上使用Java(不确定是否重要)并在应该返回0的值(如pi / 2)上调用Math.cos()而不是返回小值,但是除非我误解,否则返回的值很小从零开始大于1 ulp。
Math.cos(Math.PI/2) = 6.123233995736766E-17 Math.ulp(Math.cos(Math.PI/2)) = 1.232595164407831E-32
这实际上是在1 ulp内,我只是感到困惑? 这是否是一个可以接受的解决这种轻微不准确的包装方法?
public static double cos(double a){ double temp = Math.abs(a % Math.PI); if(temp == Math.PI/2) return 0; return Math.cos(a); }
不要忘记Math.PI/2
是近似值。 它不会完全是 pi / 2,所以cos(Math.PI/2)
的结果不会完全为0. Math.cos
可能会返回一个非常精确的余弦值,该值是由返回的精确值返回的。计算Math.PI/2
。
你永远不应该使用==
和双打。 您必须始终在误差范围内。 如果你问我,10 -17是很好的精度。 10 -32的 Ulp图只是10 -17数量级的双倍的预先计算,因为2.220446049250313E-16是10 0幅度的数字的精度。
这是一个常见的错误,当你开始时,这个链接有一个非常技术性的讨论原因。 http://docs.sun.com/source/806-3568/ncg_goldberg.html
但是在它最简单的forms中,就像我们不能在十进制系统中完全代表1/3一样,有些值无法在二进制系统中准确表示