为什么指定 BigDecimal.equals 来分别比较值和缩放?

2022-09-01 00:31:32

这不是一个关于如何比较两个对象的问题 - 我知道你可以使用而不是这样做,因为记录如下:BigDecimalcompareToequalsequals

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

问题是:为什么以这种看似违反直觉的方式指定?也就是说,为什么能够区分2.0和2.00很重要equals

这似乎一定是有原因的,因为指定方法的文档指出:ComparablecompareTo

强烈建议(尽管不是必需的)自然排序与等式一致

我想一定有充分的理由无视这一建议。


答案 1

因为在某些情况下,精度的指示(即误差幅度)可能很重要。

例如,如果您要存储两个物理传感器的测量值,则可能其中一个传感器的精度是另一个的 10 倍。陈述这一事实可能很重要。


答案 2

一般规则是,两个相等的值应该可以相互替换。也就是说,如果使用一个值执行计算会得到一些结果,那么将一个值代入相同的计算中应该给出一个结果,即第一个结果。这适用于作为值的对象,例如 、 、 等。equalsequalsequalsStringIntegerBigDecimal

现在考虑值 2.0 和 2.00。我们知道它们在数字上是相等的,并且它们返回0。但返回 false。为什么?BigDecimalcompareToequals

下面是一个它们不可替代的示例

var a = new BigDecimal("2.0");
var b = new BigDecimal("2.00");
var three = new BigDecimal(3);

a.divide(three, RoundingMode.HALF_UP)
==> 0.7

b.divide(three, RoundingMode.HALF_UP)
==> 0.67

结果显然是不等的,因此 的值不可替代 。因此,应该是假的。aba.equals(b)


推荐