为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 0.4 和 0.40 与 BigDecimal 不同?

为什么 0.4 和 0.40 与 BigDecimal 不同?

慕斯王 2023-02-23 09:56:53
我读过 BigDecimal 是用 Java 表示金钱的方法。但我不明白为什么我的一个单元测试失败并显示以下消息:org.opentest4j.AssertionFailedError:    Expected :0.40  Actual   :0.4“实际”值是 的结果BigDecimal.valueOf(0.398).setScale(2, RoundingMode.HALF_UP)。所以我想我的问题有两个部分:为什么不将这些值视为相等?我怎样才能以不会触发这种不匹配的方式将 0.40 美元表示为 BigDecimal?
查看完整描述

1 回答

?
PIPIONE

TA贡献1829条经验 获得超9个赞

BigDecimals 是数字和“比例”的组合。2 BD 不认为自己相等,除非两者相等。我建议使用.compareTo(other) == 0)来获得答案。

NB:我不认为使用 BD 是做货币的好方法。

通常有两种处理货币的方法。简单的方法和困难的方法。

简单的方法是将美分存储在intor中long。因此,将 $0.40 简单地存储为40,而 $12.50 之类的东西将存储为1250。你现在有 2 个问题:你不能代表半美分,并且可能会发生溢出(你不能代表高于 2^31-1 美分的金额,但那是......很多美分。让它成为long我们远远超过整个世界的 GDP)。

但是,半美分通常是一个问题。拿这个问题来说:

我有 4 美分。我想把这些分给 3 个人。

那么我们该怎么办?BigDecimal 在这里帮不了你;你不能用 BD 完美地表示 4 除以 3。你必须在某个地方四舍五入(它是 1.33333333 ...... BD 不能代表无限序列)。即使它可以或者您决定以某个惊人的数量(比如说 200 位)四舍五入,现在又如何呢?你不能告诉你的银行转账三分之一美分。没有简单的答案:如果这是您的应用程序需要做的,那么您需要决定如何处理它。例如,“剩余的一分钱用于房屋”或“软件随机选择一个收件人;他们得到 2 美分,另外 2 个得到 1 美分)。

换句话说,如果“只使用一个 int/long”不这样做,那么 BigDecimal 很可能也不好。


查看完整回答
反对 回复 2023-02-23
  • 1 回答
  • 0 关注
  • 80 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信