十进制与双精度! – 我应该使用哪一个?
我不断看到人们在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