我一直看到人们在 C# 中使用双打。我知道我在某处读到双打有时会失去精度。我的问题是什么时候应该使用双精度类型,什么时候应该使用十进制类型?哪种类型适合货币计算?(即超过 1 亿美元)
7 回答
为了钱,总是十进制。这就是它被创建的原因。
如果数字必须正确相加或平衡,请使用小数。这包括人们可能手动进行的任何财务存储或计算、分数或其他数字。
如果数字的确切值不重要,请使用 double 来提高速度。这包括已经存在“有效数字位数”的图形、物理或其他物理科学计算。
我的问题是什么时候应该使用双精度类型,什么时候应该使用十进制类型?
decimal
因为当您使用 10^(+/-28) 范围内的值并且您对基于 10 表示的行为有期望时 - 基本上是金钱。
double
因为当您需要相对精度(即在大值上丢失尾随数字的精度不是问题)时,需要跨越完全不同的量级 -double
涵盖超过 10 ^(+/- 300)。科学计算是最好的例子。
哪种类型适合货币计算?
十进制,十进制,十进制
不接受替代品。
最重要的因素是,double
作为二进制分数实现,根本无法准确表示许多decimal
分数(如 0.1),并且它的总位数更小,因为它是 64 位宽,而decimal
. 最后,金融应用程序通常必须遵循特定的舍入模式(有时是法律规定的)。decimal
支持这些;double
才不是。
System.Single / float - 7 位
System.Double / double - 15-16 位
System.Decimal / decimal - 28-29 位有效数字
我被错误的类型(几年前)刺痛的方式是大量的:
- £520,532.52 - 8 位数
- £1,323,523.12 - 9 位数
你用完一百万的浮动。
15 位货币价值:
- 1,234,567,890,123.45 英镑
9万亿加倍。但是对于除法和比较,它会更加复杂(我绝对不是浮点数和无理数方面的专家 -请参阅 Marc 的观点)。混合小数和双精度会导致问题:
如果使用十进制数,则使用浮点数的数学或比较运算可能不会产生相同的结果,因为浮点数可能不完全接近十进制数。
我什么时候应该使用双精度而不是十进制?有一些类似且更深入的答案。
使用double
而不是decimal
用于货币应用程序是一种微优化——这是我看待它的最简单的方式。
小数用于精确值。Double 用于近似值。
USD: $12,345.67 USD (Decimal)
CAD: $13,617.27 (Decimal)
Exchange Rate: 1.102932 (Double)
为了钱:decimal
。它需要更多的内存,但没有像double
有时那样的舍入问题。
绝对使用整数类型进行货币计算。
这一点怎么强调都不过分,因为乍一看,浮点类型似乎就足够了。
这是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
如您所见,美元消失了。
如果您使用整数类型,它工作正常:
>>> 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