ryv*_*age 5 java mysql jdbc joda-money
尝试从 MySQL 数据库读取的 BigDecimal 创建 Joda-MoneyMoney对象会引发错误。
这段代码:
PreparedStatement p_stmt = ...;
ResultSet results = ...;
Money amount = Money.of(CurrencyUnit.USD, results.getBigDecimal("amount"));
Run Code Online (Sandbox Code Playgroud)
抛出这个:
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)
Run Code Online (Sandbox Code Playgroud)
我实际上已经通过添加舍入解决了该错误:
Money amount = Money.of(CurrencyUnit.USD, results.getBigDecimal("amount"), RoundingMode.HALF_UP);
Run Code Online (Sandbox Code Playgroud)
但是,我对这个解决方案持怀疑态度。是最好的吗?
我用来按照这个 SO 答案DECIMAL(19,4)将货币值存储在数据库上。老实说,这有点让我困惑,为什么那里的回答者要求数据库上的小数点后 4 位精度,但我倾向于相信高价值的答案,并且我认为他们知道他们在说什么,并且我会后悔没有遵循他们的要求建议。然而 Joda-Money 不喜欢美国货币的小数点后 4 位精度。也许是国际标准要求小数点后 4 位精度?没有把握..DECIMAL(19,4)
为了使问题简洁:
RoundingMode.HALF_UP解决此错误的理想解决方案吗?DECIMAL(19,4)吗DECIMAL(19,2)?Joda Money 和 BigDecimal 为每种货币类型定义了一个“规模”。
规模是没有。货币使用的小数位数。
因此美元的小数位数为 2(小数点后两位小数)。
如果您尝试从具有超过两位小数的源实例化美元货币的 Money 实例,那么您将收到比例错误。例如
20.99 is fine
20.991 throws an error.
Run Code Online (Sandbox Code Playgroud)
其他货币允许不同的小数位数。
根据文档,RoundMode.UNNECESSARY如果实际需要舍入,实际上会抛出异常。
例如:假设美元的小数位数为 2,则预计有 2 位小数。
使用:
Money money = Money.of(CurrencyUnit.USD, value, RoundingMode.UNNECESSARY);
Run Code Online (Sandbox Code Playgroud)
价值:
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
Run Code Online (Sandbox Code Playgroud)
四舍五入和金钱始终是一个问题。我的方法是将正确的比例存储在数据库中
例如:如果是美元,则 DECIMAL(19,2)
使用RoundingMode.HALF_UP。
做乘法和除法时要小心。在除法之前进行乘法将减少舍入问题。如果你在做算术的时候四舍五入,你应该没问题。
| 归档时间: |
|
| 查看次数: |
3122 次 |
| 最近记录: |