java 比较Java中的浮点数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5923682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing floating point numbers in Java
提问by Klems
Possible Duplicate:
Manipulating and comparing floating points in java
可能的重复:
在 Java 中操作和比较浮点数
Am I supposed to use an Epsilon while comparing floating point numbers in Java ? Does the Float.compare(float f1, float f2) static method is safe to use ?
我应该在比较 Java 中的浮点数时使用 Epsilon 吗?Float.compare(float f1, float f2) 静态方法是否可以安全使用?
Thanks !
谢谢 !
EDIT : I think I got it.
编辑:我想我明白了。
When I write, let's say, 3.6f in eclipse, the compilator interpret this number as 3.6. However, when I write 1.2f * 3.0f, the result is 3.6000001. While mathematically this is false, these two results are obviously inequals. Hence the need to have an epsilon while checking equality.
当我在 Eclipse 中编写 3.6f 时,编译器将此数字解释为 3.6。但是,当我写1.2f * 3.0f时,结果是3.6000001。虽然在数学上这是错误的,但这两个结果显然是不等的。因此,在检查相等性时需要有一个 epsilon。
However, when I write 0.0f in eclipse, the compilator interpret this as 0 strictly, because IEEE 754 is able to handle it correctly. Therefore, ensuring a float is strictly positive with (value > 0.0f) is correct.
但是,当我在 Eclipse 中编写 0.0f 时,编译器将其严格解释为 0,因为 IEEE 754 能够正确处理它。因此,确保 (value > 0.0f) 的浮点数严格为正是正确的。
The only problem I see is when the computer doesn't use IEEE 754 representation, and instead use a representation which doesn't handle 0 correctly.
我看到的唯一问题是当计算机不使用 IEEE 754 表示,而是使用不能正确处理 0 的表示时。
Am I right ?
我对吗 ?
回答by Marek Sebera
Math.ulp() method has a practical use in testing. As you undoubtedly know, you should usually not compare floating-point numbers for exact equality. Instead, you check that they are equal within a certain tolerance. For example, in JUnit you compare expected to actual floating-point values like so:
Math.ulp() 方法在测试中有实际用途。毫无疑问,您通常不应该比较浮点数以确保完全相等。相反,您检查它们在特定容差内是否相等。例如,在 JUnit 中,您将预期值与实际浮点值进行比较,如下所示:
assertEquals(expectedValue, actualValue, 0.02);
assertEquals(expectedValue, actualValue, 0.02);
This asserts that the actual value is within 0.02 of the expected value. However is 0.02 a reasonable tolerance? If the expected value is 10.5 or -107.82, then 0.02 is probably fine. However, if the expected value is several billion, then the 0.02 may be completely indistinguishable from zero. Often what you should test is the relative error in terms of ULPs. Depending on how much accuracy the calculation requires, you usually select a tolerance somewhere between 1 and 10 ULPs. For example, here I specify that the actual result needs to be within 5 ULPs of the true value:
这断言实际值在预期值的 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));
assertEquals(expectedValue, actualValue, 5*Math.ulp(expectedValue));
http://www.ibm.com/developerworks/java/library/j-math2/index.html
http://www.ibm.com/developerworks/java/library/j-math2/index.html
回答by duffymo
Yes, it's advisable to use a tolerance to check the absolute value of the difference between two floating point numbers.
是的,建议使用容差来检查两个浮点数之间差异的绝对值。
Compare tells you if one double is less than, equal to, or greater than another. It won't tell you how close they are to one another, so, no, it's no safer than comparing with ==
.
比较会告诉您一个 double 是小于、等于还是大于另一个。它不会告诉您它们彼此之间的接近程度,因此,不,这并不比与==
.