为什么BigDecimal(“5.50”)不等于BigDecimal(“5.5”)以及如何解决此问题?

其实,我find了可能的解决办法

//returns true new BigDecimal ("5.50").doubleValue () == new BigDecimal("5.5").doubleValue () 

当然,可以用Math.abs (v1 - v2) < EPS这样的东西来改进,使得比较更稳健,但问题是这个技术是可以接受的还是有更好的解决scheme呢?

如果有人知道为什么Javadevise者决定以这种方式实现BigDecimal的平等,那么读起来会很有趣。

来自BigDecimal的javadoc

等于

public boolean equals(Object x)

将此BigDecimal与指定的Object进行比较以获得相等性。 与compareTo不同的是,这个方法只有在两个BigDecimal对象的值和比例相等的情况下才会相等(因为这个方法比较2.0不等于2.00)

只需使用compareTo() == 0

总体来说,使用==来比较双打似乎是一个糟糕的主意 。

你可以在你正在比较的数字上调用setScale来做同样的事情:

 new BigDecimal ("5.50").setScale(2).equals(new BigDecimal("5.5").setScale (2)) 

你将在哪里设置比例尺:

 BigDecimal a1 = new BigDecimal("5.051"); BigDecimal b1 = new BigDecimal("5.05"); // wow, this is awkward in Java int maxScale = Collections.max(new ArrayList() {{ a1.scale(), b1.scale()}}); System.out.println( a1.setScale(maxScale).equals(b1.setScale(maxScale)) ? "are equal" : "are different" ); 

尽pipe使用compareTo() == 0是最好的答案。 在我上面的方法中,其中一个数字的规模的增加可能是compareMagnitude方法文档提到的“不必要的通货膨胀”:

 /** * Version of compareTo that ignores sign. */ private int compareMagnitude(BigDecimal val) { // Match scales, avoid unnecessary inflation long ys = val.intCompact; long xs = this.intCompact; 

当然比较容易使用,因为它已经为你实现了。

最简单的expression式比较忽略前导零是从Java 1.5:

 bd1.stripTrailingZeros().equals(bd2.stripTrailingZeros())