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

如果我使用这样的比较(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? 

一般来说,由于很多十进制数不能精确地表示为floatdouble float值,所以不安全。 如果数字之间的差异小于一些“小”值(通常用数学文献中的希腊’epsilon’字符表示),则经常说明的解决方案是测试。

但是 – 你需要小心谨慎地进行测试。 例如,如果你写:

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

其中ab应该是“相同的”,你正在测试绝对误差 。 如果你这样做,你可能会遇到麻烦,如果ab分别是(分别为1,999,999.992,000,000.00 。这两个数字之间的差异小于float 那个规模的最小可表示值,但它比我们的大得多)选择了epsilon。

可以说,更好的方法是使用相对误差 ; 例如编码(防御性地)为

 if (a == b || Math.abs(a - b) / Math.max(Math.abs(a), Math.abs(b)) < 0.000001) { System.err.println("close enough to be equal"); } 

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

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


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

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

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

你需要做一些照顾。

 1.0 + 2.0 == 3.0 

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

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

如果b == c。

 b / 3.0 == 10.0 / 3.0 

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

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

如果您正在测试受浮点近似计算的结果,则应进行相等测试,直至达到公差。

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

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

如果b == c ,则Math.sqrt(b) == Math.sqrt(c) – 这是因为sqrt函数反正返回double。

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

b - c < 0.000001

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

对于:

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

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

对于:

 b / 3 == 10 / 3 

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

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

例如

 Math.abs(a - b) < EPS 

EPS可以是0.0000001。

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

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

 Float.compare(float1,float2)==0 

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

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

b是浮点数,10是整数然后如果你比较你的这个critearia然后它将给出false,因为…

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

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