60

实际上,我找到了可能的解决方案

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

当然,可以通过Math.abs (v1 - v2) < EPS使比较更健壮的方法来改进它,但问题是这种技术是否可以接受或者是否有更好的解决方案?

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

4

3 回答 3

101

来自 BigDecimal 的 javadoc

等于

public boolean equals(Object x)

将此BigDecimal与指定Object的相等性进行比较。与 不同compareTo的是,此方法仅当两个BigDecimal对象的值和比例相等时才认为它们相等(因此,通过此方法比较时,2.0 不等于 2.00)

只需使用compareTo() == 0

于 2010-10-05T18:24:07.420 回答
13

比较忽略尾随零的最简单表达式是从 Java 1.5 开始:

bd1.stripTrailingZeros().equals(bd2.stripTrailingZeros())
于 2015-12-02T13:47:51.880 回答
11

一般来说,使用==比较双打似乎是个坏主意

您可以在要比较的数字上调用 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它更容易使用,因为它已经为您实现了。

于 2010-10-05T18:42:10.270 回答