【问题标题】:BigDecimal equals() versus compareTo()BigDecimal equals() 与 compareTo()
【发布时间】:2011-10-10 20:33:52
【问题描述】:

考虑简单的测试类:

import java.math.BigDecimal;

/**
 * @author The Elite Gentleman
 *
 */
public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        BigDecimal x = new BigDecimal("1");
        BigDecimal y = new BigDecimal("1.00");
        System.out.println(x.equals(y));
        System.out.println(x.compareTo(y) == 0 ? "true": "false");
    }

}

您可以(有意识地)说x 等于y(不是对象引用),但是当您运行程序时,会显示以下结果:

false
true

问题:BigDecimal中的compareTo()equals()有什么区别,compareTo可以确定x等于y

PS:我看到 BigDecimal 在 equals() 方法上有一个 inflate() 方法。 inflate() 究竟做了什么?

【问题讨论】:

  • 广告inflate():它不是公共 API 的一部分,因为它只操纵内部表示,对“外部”没有可见的影响。所以除非你真的想深入研究BigDecimal的实现,否则我建议你忽略这个方法。
  • 简单说明和sn-ps源码可以看here

标签: java equals bigdecimal compareto


【解决方案1】:

答案在the JavaDoc of the equals() method

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

换句话说:equals() 检查BigDecimal 对象是否在每个方面完全相同相同。 compareTo() "only" 比较它们的数值。

至于为什么equals()会这样,in this SO question已经回答了。

【讨论】:

  • 如果您不仔细阅读 JavaDoc,那是 BigDecimal 的一个非常棘手的部分。 :) - 在我们意识到差异之前,我们从中得到了一些奇怪的错误。
  • 标准 API 的许多部分碰巧在“不直观”的情况下,当直观的事情不正确时。 BigDecimal 就是这样的一件事。因此,应始终检查 JavaDoc。 至少一旦你发现一些奇怪的事情正在发生。
  • 有趣。阅读您的答案后,我刚刚检查了 Comparable 并指出与 equals 的一致性“强烈推荐(但不是必需)”
  • @StephenC 我认为存在这种不一致是不正确的
【解决方案2】:

我看到 BigDecimal 在 equals() 方法上有一个 inflate() 方法。 inflate() 实际上是做什么的?

基本上,inflate() 会在必要时调用 BigInteger.valueOf(intCompact),即它会创建未缩放的值,该值存储为来自 long intCompactBigInteger。如果您不需要 BigInteger 并且未缩放的值适合 long BigDecimal 似乎会尽可能地节省空间。

【讨论】:

  • 我不知道你写了什么(尤其是最后一句话)。
  • @The Elite Gentlement 最后一句应该只是说内部BigDecimal 将其未缩放的值保存在longBigInteger 中。如果内部不需要BigInteger,则不会创建它,但如果需要它(例如,当equals 遇到膨胀和非膨胀时BigDecimal) inflate()` 用于创建它。 - 总结一下:inflate() 会在必要时处理内部转换,并且由于它是私有的,因此对于该类的用户来说应该无关紧要。
【解决方案3】:

我相信正确的答案是使两个数字(BigDecimals)具有相同的比例,然后我们可以决定它们是否相等。例如,这两个数字是否相等?

1.00001 and 1.00002

嗯,这取决于规模。在 5 级(小数点后 5 个)上,不,它们不一样。但在较小的十进制精度(4 级或更低)上,它们被认为是相等的。 所以我建议让两个数字的比例相等,然后比较它们。

【讨论】:

    【解决方案4】:

    你也可以用double值比较

    BigDecimal a= new BigDecimal("1.1"); BigDecimal b =new BigDecimal("1.1");
    System.out.println(a.doubleValue()==b.doubleValue());
    

    【讨论】:

    • 请尽量避免这种方案。甚至双打也应该与“epsilon”进行比较。拥有 BigDecimal 并将其作为双打进行比较是没有意义的。您很有可能会打自己的腿。
    • 必须使用 epsilons 比较双值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    相关资源
    最近更新 更多