【问题标题】:One BigDecimal approximately equals another Bigdecimal一个 BigDecimal 大约等于另一个 BigDecimal
【发布时间】:2018-01-08 10:14:25
【问题描述】:

我广泛使用 BigDecimals。我经常需要进行长时间的计算,然后比较结果。由于这些冗长的计算,答案不是1,而是0.9999999...。这就是为什么我不能准确地比较 BigDecimals 而只能比较某个错误。

如何检查一个 BigDecimal 是否位于另一个 BigDecimal 的 epsilon 内?

备注:我已经知道answer.subtract(expected).abs().compareTo(epsilon) < 0。但是我必须一遍又一遍地写它,我正在寻找一种更简单的方法来做到这一点。

【问题讨论】:

  • 减去并与您的ε进行比较,这不会太难吧?
  • 如果您的计算不准确,为什么不直接使用double? Commons Math 有一个 utility library 用于将浮点数与 epsilon 进行比较。
  • 你需要图书馆做什么?只需将差异与您的 epsilon 而不是与 0 进行比较,您就完成了。
  • @Zinki,我知道这种方式,我要求一种更优雅的方式来做到这一点
  • 如果你不想一遍又一遍地写一些重要的东西(你不应该这样做),你应该把它放在一个方法中,然后调用那个方法。

标签: java precision bigdecimal


【解决方案1】:
BigDecimal error = new BigDecimal(1e-5);    

BigDecimal a = new BigDecimal(100);
BigDecimal b = new BigDecimal(11.2);

if (a.subtract(b).abs().compareTo(error) < 0) {
    // a approximately equals b
}

【讨论】:

  • 你需要setScale
  • @ACV 为什么我需要 setScale?
【解决方案2】:

只需在 util 类或其他东西中添加您自己的方法:

if (a.subtract(b).abs().setScale(precision, RoundingMode.HALF_EVEN).compareTo(epsilon)>0) { //they are not different }

【讨论】:

  • 你需要一个绝对算术。
【解决方案3】:

没有 Div 0 问题

public static boolean almostEqual(BigDecimal a, BigDecimal b) {
    int scale = Math.min(a.scale(), b.scale()) -1;
    return a.setScale(scale, RoundingMode.HALF_UP)
               .compareTo(b.setScale(scale, RoundingMode.HALF_UP)) == 0;

}

规模可控

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多