试图从从Money数据库读取的BigDecimal创建Joda货币MySQL对象会引发错误。
此代码:
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上存储货币值。老实说,我有点搞不懂为什么那里的答案要求在DB上精确计算4位小数,但我倾向于相信高价值的答案,我想他们知道他们在说什么,我会后悔不听从他们的建议。然而,尤达-货币不喜欢4小数位的精度与美国货币。也许DECIMAL(19,4)是一个国际标准,他们需要小数点4位的精度?不确定..。
为了使问题简洁:
RoundingMode.HALF_UP是解决此错误的理想解决方案吗?DECIMAL(19,4)更改为DECIMAL(19,2)?发布于 2018-08-01 00:21:05
Joda Money和BigDecimal为每种货币类型定义了一个“规模”。
比例尺是否定的。货币使用的小数位数。
因此,美元的刻度是2(小数位后的两个小数位)。
如果您试图从一个有两个以上小数位的源实例化美元货币的货币实例,那么您将得到一个比例尺错误。例如:
20.99 is fine
20.991 throws an error.其他货币允许不同的小数位数。
根据文档,如果实际需要舍入,RoundMode.UNNECESSARY实际上会抛出异常。
假设美元是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四舍五入和金钱总是一个问题。我的方法是在db中存储正确的比例尺。
如果是美元,那么小数点(19,2)
使用RoundingMode.HALF_UP。
做乘法除法时要小心。在除法之前做乘法会减少四舍五入的问题。如果你在做算术的时候转一圈,你就会没事的。
发布于 2014-05-30 17:17:12
是的,不是个好办法。你代表的是钱,所以你不能把钱收起来,放几分钱。)
问题是,CurrencyUnit.USD的数字数为2,例如: 1.45,而来自DB的数字大约是1.45343,这可能导致了规模上的差异。试着用BigMoney而不是金钱来代表金钱。
BigMoney amount = BigMoney .of(CurrencyUnit.USD, results.getBigDecimal("amount"));发布于 2016-10-25 20:43:27
有同样的问题,并通过添加不必要的舍入模式来解决:
@Test(dataProvider = "moneyValueProvider")
public void testMoneyFromFloat(String currency, Float value) {
CurrencyUnit cu = CurrencyUnit.of(currency);
//Double dVal = Double.valueOf(value.toString());
BigDecimal bigDecimal = new BigDecimal(value.toString());
Money money = Money.of(cu, bigDecimal, RoundingMode.UNNECESSARY);
Assert.assertNotNull(money);
Assert.assertEquals(bigDecimal.doubleValue(), money.getAmount().doubleValue());
}
@DataProvider
public static Object[][] moneyValueProvider() {
return new Object[][] {
{"GBP", 22.5f},
{"GBP", 57.8f},
{"JPY", 15000.0f}
};https://stackoverflow.com/questions/23598360
复制相似问题