我了解使用Double数据类型进行资金计算的是asking for trouble,因此应该使用Decimal。
我觉得这很愚蠢,但是在使用Double数据类型来存储或传输Money值时,是否存在潜在的问题,只要在进行计算时将其转换为Decimal?
我问这个是因为我手上有一个旧的应用程序需要维护,而且它到处使用Double。为了节省工作,我想只重构实际进行计算的部分,使用Decimal而不是Double。我想将其余部分单独留在只有数据传输,序列化等管道代码的地方。
答案 0 :(得分:4)
在double
中存储数据时,不仅在检索数据时存在精度损失。所以不,这不能解决你的问题。你不能神奇地检索丢失的精度。
答案 1 :(得分:1)
答案取决于您需要“运输”的有效位数。十进制为您提供28位数,而双数为您提供约15位左右。因此,如果您的值在+/- 10万亿(假设2位小数)的范围内,那么您应该没问题。如果您使用其他货币,您可能需要更多小数位,因此范围将减少到例如+/- 1000亿,小数点后4位。
答案 2 :(得分:0)
你不应该使用浮点值来存储货币价值。
MAybe使用BigDecimal .. https://blogs.oracle.com/CoreJavaTechTips/entry/the_need_for_bigdecimal
答案 3 :(得分:-1)
例如,您正在插入一个事务,假设所有计算都是使用十进制数据类型
执行的Amount : $45.35
TAX : $ 1.72
-----------------
Total : $47.07
现在我们假设您制作销售凭证并存储所有三个值。存储时,将所有三个值转换为double。所以它变成了二进制浮点值。
如果用户再次尝试打开旧的销售凭证,则尝试检索这三个值;它可能由于舍入和转换(从double到十进制)而发生,您会收到不同的值,可能如下所示
Amount : $45.36 (//changed)
TAX : $ 1.72
-----------------
Total : $47.07 (//Total sum is as stored, but when you sum
//actual values retrieved, they are different.)
这是基于我的经验,目前我无法在技术上解释这种情况。
也可能只存储Amount
和Tax Rate
,但是当您添加它们时,总数将比客户的实际销售凭证多1美分:
Amount : $45.36 /*View after sales*/ Amount : $45.35 /*What customer's*/
TAX : $ 1.72 TAX : $ 1.72 /*voucher says:*/
----------------- -----------------
Total : $47.07 Total : $47.07