2013-03-22 87 views
15

什么是比较两个浮点数值以获得精确相等的优雅,可读和非冗长的方法?检查两个浮点数/双精度值是否相等

听起来很简单,它是一个邪恶的问题。该==运营商没有得到楠完成工作,并且还具有零特殊处理:

(+0.0 == -0.0) -> true 
Double.NaN == Double.NaN -> false 

但我想,以确定是否两个值是完全一样的(但我不照顾针对不同的NaN模式,所以任何NaN ==任何其他NaN - > true)。

可以这个丑八怪一段代码做到这一点:

Double.doubleToLongBits(a) == Double.doubleToLongBits(b) 

有没有更好的方式来写这个(并意图明显)?

+0

你不一天为什么你想这样做。如果他们真的是浮点数,你的答案将不会有意义。 – Julian 2013-03-22 18:18:35

+0

@ Julian参见PeterLawrey的答案就是一个非常有意义的例子。然而,我的应用程序是一个对象的equals()方法,其中float是主键的一部分(不是我自己选择的)。浮点通常无法直观的假设,所以我很小心地覆盖边缘案例。 – Durandal 2013-03-25 10:53:16

+0

对不起,你不能做得更好,你的“丑陋的怪物片”已经是完美的了...... – 2013-03-25 11:36:16

回答

10

我想说,你已经拥有了最好的方法。它清楚地表明您对按位值表示值感兴趣。您恰好将这些位转换为long作为方便的64位类型,它没有任何时髦行为。

如果你不希望它频繁出现在你的代码库做什么,只是添加一个方法把它包起来:

public static boolean bitwiseEqualsWithCanonicalNaN(double x, double y) { 
    return Double.doubleToLongBits(x) == Double.doubleToLongBits(y); 
} 

请注意,根据您的问题,这确实不同的NaN值之间分化。如果您想在稍后的日期执行此操作,则需要使用Double.toRawLongBits

+0

Mhhh,你和彼得的答案都有他们的吸引力。为了清楚起见,我认为静态助手会更好一些,因为我可以对方法发表评论,任何人都会在这个问题上磕磕碰碰。尽管如此,仍在考虑一个好的方法名称。 – Durandal 2013-03-22 14:48:07

22

您可以使用

Double.compare(a, b) == 0 

从Javadoc文档的compareTo

  • Double.NaN通过这种方法被认为比其他所有double值(包括Double.POSITIVE_INFINITY等于本身和更大)。
  • 该方法认为0.0d大于-0.0d。
+0

那么这两个0的区别是否恰当呢? – 2013-03-22 14:26:15

+0

它会做NaNs。检查-0和0 – 2013-03-22 14:27:05

+1

我刚刚检查过。它的确如此。尼斯 - 虽然不*显然*正确,我会说。 (我会直觉地预期*声称正数和负数是相等的,我更喜欢这个代码,这使得它对于精确的比特感兴趣。) – 2013-03-22 14:27:39

相关问题