在Java中直接比较2 float / double是否安全?

时间:2011-07-22 06:09:18

标签: java android

如果我使用这样的比较(a是int,b和c是float / double)是否安全:

a == b
b == c

它可能听起来很荒谬,但在我的旧编程语言中,有时1 + 2 == 3是假的(因为左侧返回2.99999999999 ......)。那怎么样:

Math.sqrt(b) == Math.sqrt(c)
b / 3 == 10 / 3 //In case b = 10, does it return true?

9 个答案:

答案 0 :(得分:12)

一般而言,由于无法将这么多十进制数精确表示为floatdouble值,因此不安全。如果数字之间的差异小于某个“小”值(通常用数学文献中的希腊'epsilon'字符表示),则经常说明的解决方案是测试。

然而 - 您需要小心谨慎地进行测试。例如,如果你写:

if (Math.abs(a - b) < 0.000001) {
    System.err.println("equal");
}

其中ab应该是“相同”,您正在测试绝对错误。如果你这样做,如果ab分别是({_ 1}}和1,999,999.99,则会遇到麻烦。这两个数字之间的差异小于最小的数字对于2,000,000.00,该值为 ,但它比我们选择的epsilon大得多。

可以说,更好的方法是使用相对错误;例如<防守地'编码为

float

但即使这不是完整的答案,因为它没有考虑某些计算导致错误累积到无法管理的比例的方式。有关详细信息,请查看this Wikipedia link

最重要的是,处理浮点计算中的错误比初看起来要困难得多。


要注意的另一点是(正如其他人所解释的)整数算法在几个方面与浮点算法的行为非常不同:

  • 如果结果不是整数,整数除法将截断
  • 整数加法减法和乘法将溢出。

无论是在编译时还是在运行时,这两种情况都会发生而没有任何警告

答案 1 :(得分:5)

你需要做一些照顾。

1.0 + 2.0 == 3.0

是正确的,因为整数是完全可表示的。

Math.sqrt(b) == Math.sqrt(c) 

如果b == c。

b / 3.0 == 10.0 / 3.0

如果b == 10.0这就是我认为你的意思。

最后两个示例比较了同一计算的两个不同实例。当您使用不可表示的数字进行不同的计算时,则完全相等的测试失败。

如果您正在测试受浮点近似计算的结果,那么应该在公差范围内进行相等测试。

你有任何特定的现实世界的例子吗?我想你会发现很少想用浮点测试相等性。

答案 2 :(得分:4)

b / 3 != 10 / 3 - 如果b是像b = 10.0f那样的浮点变量,那么b / 3是3.3333,而10/3是整数除法,所以等于3。

如果是b == c,那么Math.sqrt(b) == Math.sqrt(c) - 这是因为sqrt函数无论如何都会返回。

通常,您不应该将等式/浮点数与等式进行比较,因为它们是浮点数,因此您可能会遇到错误。您几乎总是希望将它们与给定的精度进行比较,即:

b - c < 0.000001

答案 3 :(得分:2)

==对于基本上任何语言的双打/浮点数,比较并不是特别安全。一个epsilon比较方法(你检查两个浮点数之间的差异相当小)是你最好的选择。

有关:

Math.sqrt(b) == Math.sqrt(c)

我不确定为什么你不会只比较b和c,但是epsilon比较也适用于此。

有关:

b / 3 == 10 / 3

由于整数除法,因为10/3 = 3,所以这不一定会给出您正在寻找的结果。您可以使用10.0 / 3,但我仍然不确定为什么您不会只比较b和10(在任何一种情况下都使用epsilon比较方法)。

答案 4 :(得分:2)

将float / double与其他东西进行比较的最安全的方法实际上就是看看它们的差异是否很小。

e.g。

Math.abs(a - b) < EPS

其中EPS可以是0.0000001。

这样可以确保精确度错误不会影响结果。

答案 5 :(得分:1)

Float包装类比较方法可用于比较两个浮点值。

Float.compare(float1,float2)==0

它将比较每个float对象对应的整数位。

答案 6 :(得分:0)

在java中,你可以将float与另一个float进行比较,并将double与另一个double进行比较。当精度相等时,将double与float进行比较时,你将得到真实

答案 7 :(得分:0)

b是浮点数,10是整数然后如果你将它们与你的这个critearia进行比较那么它会给出错误,因为......

b = flaot (meance ans 3.33333333333333333333333)
10 is integer so that make sence.

答案 8 :(得分:0)

如果你想要一个更完整的解释,这里有一个很好的解释:http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html(但它有点长)