我是否应该在比较Java中的浮点数时使用Epsilon? Float.compare(float f1,float f2)静态方法是否可以安全使用?
谢谢!
编辑:我想我明白了。当我写作时,比如说,在日食中3.6f,编译器将这个数字解释为3.6。但是,当我写1.2f * 3.0f时,结果是3.6000001。虽然在数学上这是错误的,但这两个结果显然是不公平的。因此,在检查相等性时需要有一个epsilon。
然而,当我在eclipse中写入0.0f时,编译器严格地将其解释为0,因为IEEE 754能够正确处理它。因此,确保浮动是严格正的(值> 0.0f)是正确的。
我看到的唯一问题是计算机不使用IEEE 754表示,而是使用不能正确处理0的表示。
我是对的吗?
答案 0 :(得分:12)
Math.ulp()方法在测试中有实际用途。毫无疑问,您通常不应该将浮点数进行比较以确保完全相等。相反,您检查它们在一定容差范围内是否相等。例如,在JUnit中,您将预期与实际浮点值进行比较,如下所示:
assertEquals(expectedValue, actualValue, 0.02);
这断言实际值在预期值的0.02之内。但是0.02合理的容差是多少?如果预期值是10.5或-107.82,则0.02可能没问题。但是,如果预期值是几十亿,那么0.02可能完全无法与零区分。通常你要测试的是ULP方面的相对误差。根据计算所需的精度,通常选择1到10个ULP之间的公差。例如,在这里我指定实际结果需要在真值的5个ULP内:
assertEquals(expectedValue, actualValue, 5*Math.ulp(expectedValue));
http://www.ibm.com/developerworks/java/library/j-math2/index.html
答案 1 :(得分:3)
是的,建议使用容差来检查两个浮点数之差的绝对值。
比较告诉您一个double是否小于,等于或大于另一个。它不会告诉你它们彼此有多接近,所以,没有,它与比较==
并不安全。