类似于BigDecimal(“1.0”)。equals(new BigDecimal(“1”)返回false的其他注意事项吗?

12

我最近发现了BigDecimal中一种我之前不知道的行为。我一直将它们用作替代double以便在需要精度的区域使用,例如在财务计算中。

然而,最近我发现了这个事实。

new BigDecimal("1.0").equals(new BigDecimal("1")) == false

我必须承认,这让我感到惊讶。我认为这是因为第一个数字的比例为1,而第二个数字的比例为0,但仍然似乎很不直观。我认为我以前从未遇到过这种情况,是因为我们一直在金融计算中使用固定比例的BigDecimals

查看BigDecimal 文档,我发现它说应使用compareTo() == 0来检查忽略比例的相等性,而equals()则比较值和比例。

在使用具有不同比例的BigDecimal时,是否还有其他类似的陷阱需要注意?


1
你的意思是,除了Java文档中已经记录的内容,你没有其他需要吗? - Chetan Kinger
5
一个类似的注意点是, new BigDecimal(0.1)BigDecimal.valueOf(0.1) 返回不同的结果。第一个是double值的表示形式,会像这样:0.1000000000000000055511151231257827021181583404541015625,而第二个是0.1 - Powerlord
2
相关(可能是重复的):https://dev59.com/WWIj5IYBdhLWcg3w24kF - Maroun
4
@Powerlord,顺便说一下 new BigDecimal(0.1f) 不等于 new BigDecimal(0.1) ;) - Peter Lawrey
1
各位,请注意,原帖作者正在寻求其他的陷阱,他已经知道了他提到的特定陷阱的原因。这不是一场比赛。 - Chetan Kinger
显示剩余8条评论
3个回答

5

3
根据equals()的JavaDoc:

compareTo不同,该方法仅当两个BigDecimal对象在值和比例上相等时才将其视为相等(因此,通过该方法比较时,2.0不等于2.00)。

因此,equals()检查对象是否完全相同compareTo()“仅”比较它们的数值。

我相信原帖作者已经知道了这个特定情况的原因。他想知道是否还有其他类似的陷阱。 - Chetan Kinger

3

BigDecimal的equals方法检查两个BigDecimal对象的内容是否相同,例如它们的toString()方法返回值是否相同。就像"1.0"和"1"不相等一样,new BigDecimal("1.0").equals(new BigDecimal("1"))也不相等,因为它们的unscaledValue()getScale()都不同。

需要注意的是,虽然您知道==不能比较内容,并且可能已经被告知.equalsString的解决方案,但它可能无法实现您对BigDecimal的预期效果。

对于compareTo方法,它必须根据大小关系进行比较,由于这些值既不大于也不小于,所以它们只能相等(但不完全相等)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接