为什么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())