我知道使用 Double 数据类型进行 Money 计算会带来麻烦 ,因此应该使用 Decimal。
问这个问题我觉得很愚蠢,但是使用 Double 数据类型来存储或传输 Money 值是否存在潜在问题,只要在计算时将其转换为 Decimal ?
我问这个是因为我手头有一个旧的应用程序要维护,而且它到处都在使用 Double。为了节省工作,我只想重构实际进行计算的部分,使用 Decimal 而不是 Double。我想把剩下的部分放在一边,它只是用于数据传输、序列化等的管道代码。
double
当您存储数据时,不仅在检索数据时会损失精度。所以不,这不能解决你的问题。您无法神奇地找回丢失的精度。
答案取决于您需要“传输”多少有效数字。Decimal 为您提供 28 位数字,而 Double 为您提供大约 15 位左右。因此,如果您的值在 +/- 10 万亿范围内(假设有 2 个小数位),您应该没问题。如果您使用其他货币,您可能需要更多的小数位,因此范围将减少到例如 +/- 1000 亿,小数点后 4 位。
你不应该使用浮点值来存储货币价值..
可能使用 BigDecimal .. https://blogs.oracle.com/CoreJavaTechTips/entry/the_need_for_bigdecimal
例如,您正在插入一个事务,假设所有计算都是使用十进制数据类型执行的
Amount : $45.35
TAX : $ 1.72
-----------------
Total : $47.07
现在我们假设您制作了一张销售凭证并存储了所有三个值。在存储时,您将所有三个值都转换为双倍。所以它变成了二进制浮点值。
如果用户再次尝试打开旧的销售凭证,则尝试检索三个值;这可能是由于四舍五入和转换(从双精度到十进制)您收到不同的值,可能如下所示
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