使用Double数据类型来传输Money值

时间:2012-05-03 04:26:20

标签: c# refactoring currency

我了解使用Double数据类型进行资金计算的是asking for trouble,因此应该使用Decimal。

我觉得这很愚蠢,但是在使用Double数据类型来存储或传输Money值时,是否存在潜在的问题,只要在进行计算时将其转换为Decimal?

我问这个是因为我手上有一个旧的应用程序需要维护,而且它到处使用Double。为了节省工作,我想只重构实际进行计算的部分,使用Decimal而不是Double。我想将其余部分单独留在只有数据传输,序列化等管道代码的地方。

4 个答案:

答案 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.)

这是基于我的经验,目前我无法在技术上解释这种情况。

也可能只存储AmountTax 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