gpt4 book ai didi

java - ResultSet::getBigDecimal 抛出 joda-money 的缩放异常

转载 作者:行者123 更新时间:2023-11-29 01:03:17 26 4
gpt4 key购买 nike

尝试从 MySQL 数据库读取的 BigDecimal 创建 Joda-Money Money 对象会引发错误。

这段代码:

PreparedStatement p_stmt = ...;
ResultSet results = ...;
Money amount = Money.of(CurrencyUnit.USD, results.getBigDecimal("amount"));

抛出这个:

java.lang.ArithmeticException: Scale of amount 1.0000 is greater than the scale of the currency USD
at org.joda.money.Money.of(Money.java:74)
at core.DB.getMoney(DB.java:4821)

我实际上通过添加舍入解决了错误:

Money amount = Money.of(CurrencyUnit.USD, results.getBigDecimal("amount"), RoundingMode.HALF_UP);

但是,我对这个解决方案持怀疑态度。这是最好的吗?

我正在使用 DECIMAL(19,4) 按照 this SO answer 将货币值存储在数据库中.老实说,这让我有点困惑,为什么那里的回答者要求 DB 的小数点后 4 位精度,但我倾向于相信高值(value)的答案,我假设他们知道他们在说什么,我会后悔没有听从他们的建议。然而,Joda-Money 不喜欢美国货币的小数点后 4 位精度。也许 DECIMAL(19,4) 是一个需要小数点后 4 位精度的国际标准?不确定..

为了使问题简洁:

  1. RoundingMode.HALF_UP 是解决此错误的理想解决方案吗?
  2. 我是否应该将 MySQL 数据库的精度从 DECIMAL(19,4) 更改为 DECIMAL(19,2)
  3. 有没有办法改变 Joda-Money 的精度?如果是:我应该吗?

最佳答案

Joda Money 和 BigDecimal 为每种货币类型定义了一个“比例”。

规模是没有的。货币使用的小数位数。

所以美元的刻度为两位(小数点后两位小数)。

如果您尝试从具有多于两位小数的源中为美元货币实例化 Money 实例,那么您将遇到比例错误。例如

20.99 is fine
20.991 throws an error.

其他货币允许不同的小数位数。

根据文档,如果确实需要舍入,RoundMode.UNNECESSARY 实际上会抛出异常。

例如:假设 USD 的小数位数为 2,则需要 2 位小数。

使用:

Money money = Money.of(CurrencyUnit.USD, value, RoundingMode.UNNECESSARY);

值:

1.20 - works fine
1.200 - works fine as whilst extra digit rounding isn't necessary.
1.201 - throws an exception as rounding is necessary

四舍五入和金钱总是一个问题。我的方法是在数据库中存储正确的比例

例如:如果 USD 那么 DECIMAL(19,2)

使用RoundingMode.HALF_UP

做乘法和除法时要小心。在除法之前进行乘法会减少舍入问题。如果你在做算术的时候四舍五入,你应该没问题。

关于java - ResultSet::getBigDecimal 抛出 joda-money 的缩放异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23598360/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com