十进制与双精度! – 我应该使用哪一个?

我不断看到人们在C#中使用双打。 我知道我读了一些双打有时会失去精度的地方。 我的问题是什么时候应该使用一个double,什么时候应该使用一个十进制types? 哪种types适合金钱计算? (即超过1亿美元)

为了钱, 总是小数。 这就是它创build的原因。

如果数字必须正确合计或平衡,请使用小数。 这包括任何财务储存或计算,分数或人们可能手动完成的其他数字。

如果数字的确切值不重要,则使用double来表示速度。 这包括graphics,物理或其他物理科学计算,其中已经有“有效位数”。

我的问题是什么时候应该使用一个double,什么时候应该使用一个十进制types?

decimal ,当你在10 ^(+/- 28)的范围内使用数值时,以及你对基于10次表示的行为有一个预期 – 基本上是金钱。

当你需要相对精确度(即在大数值后面的数字中失去精确度不是问题)时,这个数字会大大超过10 ^(+/- 300)。 科学计算是最好的例子。

哪种types适合金钱计算?

十进制, 十进制十进制

不接受替代品。

最重要的因素是,作为二进制小数实现的double ,根本不能精确地表示很多decimal部分(如0.1) 因为它是64位宽,而decimal位数是128位,所以其总位数较小。 最后,财务申请通常必须遵循特定的四舍五入模式 (有时由法律规定)。 decimal 支持这些 ; double不。

十进制是为了确切的值。 双是为近似值。

 USD: $12,345.67 USD (Decimal) CAD: $13,617.27 (Decimal) Exchange Rate: 1.102932 (Double) 

System.Single / float – 7位数字
System.Double / double – 15-16位数
System.Decimal / decimal – 28-29有效数字

我错误的types(好几年前)被刺痛的方式是大量的:

  • 520,532.52英镑 – 8位数字
  • £1,323,523.12 – 9位数字

你以100万美元的价格用完了。

15位货币值:

  • £1,234,567,890,123.45

9万亿加双。 但是通过分割和比较,它更加复杂(我绝对不是浮点数和非理性数的专家 – 参见Marc的观点 )。 混合小数和双打会导致问题:

如果使用十进制数字,则使用浮点数字的math或比较操作可能不会产生相同的结果,因为浮点数字可能不精确地接近十进制数字。

什么时候应该使用双精度而不是小数? 有一些相似和更深入的答案。

对货币应用使用double精度而不是decimal是微观优化 – 这是我看最简单的方法。

为了钱: decimal 。 它花费更多的内存,但没有像double有时有圆整的麻烦。

绝对使用整数types为您的货币计算。 这一点不能被强调,因为乍一看似乎浮点types是足够的。

这里是一个Python代码示例:

 >>> amount = float(100.00) # one hundred dollars >>> print amount 100.0 >>> new_amount = amount + 1 >>> print new_amount 101.0 >>> print new_amount - amount >>> 1.0 

看起来很正常。

现在用10 ^ 20津巴布韦元再次尝试

 >>> amount = float(1e20) >>> print amount 1e+20 >>> new_amount = amount + 1 >>> print new_amount 1e+20 >>> print new_amount-amount 0.0 

你可以看到,美元消失了。

如果您使用整数types,它工作正常:

 >>> amount = int(1e20) >>> print amount 100000000000000000000 >>> new_amount = amount + 1 >>> print new_amount 100000000000000000001 >>> print new_amount - amount 1 

我认为比特宽度的主要区别在于十进制的指数为10,双精度为2

http://software-product-development.blogspot.com/2008/07/net-double-vs-decimal.html