实际上,我找到了可能的解决方案
//returns true
new BigDecimal("5.50").doubleValue() == new BigDecimal("5.5").doubleValue()
当然,可以通过Math.abs (v1 - v2) < EPS
使比较更健壮的方法来改进它,但问题是这种技术是否可以接受或者是否有更好的解决方案?
如果有人知道为什么 java 设计者决定以这种方式实现 BigDecimal 的等号,那么阅读起来会很有趣。
实际上,我找到了可能的解决方案
//returns true
new BigDecimal("5.50").doubleValue() == new BigDecimal("5.5").doubleValue()
当然,可以通过Math.abs (v1 - v2) < EPS
使比较更健壮的方法来改进它,但问题是这种技术是否可以接受或者是否有更好的解决方案?
如果有人知道为什么 java 设计者决定以这种方式实现 BigDecimal 的等号,那么阅读起来会很有趣。
来自 BigDecimal 的 javadoc
等于
public boolean equals(Object x)
将此
BigDecimal
与指定Object
的相等性进行比较。与 不同compareTo
的是,此方法仅当两个BigDecimal
对象的值和比例相等时才认为它们相等(因此,通过此方法比较时,2.0 不等于 2.00)。
只需使用compareTo() == 0
比较忽略尾随零的最简单表达式是从 Java 1.5 开始:
bd1.stripTrailingZeros().equals(bd2.stripTrailingZeros())
一般来说,使用==
比较双打似乎是个坏主意。
您可以在要比较的数字上调用 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" );
不过,使用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;
当然compareTo
它更容易使用,因为它已经为您实现了。