我总是在c#中告诉double类型的变量不适合赚钱.所有奇怪的事情都可能发生.但我似乎无法创建一个示例来演示其中的一些问题.谁能提供这样的例子?
(编辑;这篇文章最初被标记为C#;一些回复指的是具体细节decimal
,因此意味着System.Decimal
).
(编辑2:我特别要求一些c#代码,所以我不认为这只是语言不可知)
非常,非常不合适.使用小数.
double x = 3.65, y = 0.05, z = 3.7; Console.WriteLine((x + y) == z); // false
(例如,从Jon的页面在这里 -推荐阅读;-p)
你会得到有效的四舍五入错误.此外,与精确值的比较非常棘手 - 您通常需要应用某种类型的epsilon来检查实际值是否接近特定值.
这是一个具体的例子:
using System; class Test { static void Main() { double x = 0.1; double y = x + x + x; Console.WriteLine(y == 0.3); // Prints False } }
是的,它不合适.
如果我没记错,double有大约17个有效数字,所以通常舍入误差将远远小于小数点.大多数财务软件使用小数点后面的4位小数,留下13位小数,因此单次操作可以使用的最大数量仍远高于美国国债.但是舍入错误会随着时间的推移而增加.如果你的软件运行很长时间,你最终会开始失去美分.某些操作会使情况变得更糟.例如,将少量添加到少量将导致显着的精度损失.
你需要定点数据类型进行资金操作,大多数人不介意你在这里和那里输了一分钱,但会计师不像大多数人.
编辑
根据这个网站http://msdn.microsoft.com/en-us/library/678hzkk9.aspx双打实际上有15到16位有效数字而不是17位数.
@Jon Skeet十进制比双精度更合适,因为它具有更高的精度,28或29位有效小数.这意味着累积舍入误差变得越来越大的可能性越小.像Boojum提到的定点数据类型(即代表美分或100分钱的整数,如我所见过的)实际上更适合.
由于decimal
使用10的倍数的比例因子,可以精确地表示像0.1这样的数字.从本质上讲,十进制类型将此表示为1/10 ^ 1,而a double
表示为104857/2 ^ 20(实际上它更像是真正的大数字/2 ^ 1023).
A decimal
可以精确地表示任何基数10值,最多有28/29位有效数字(如0.1).一个double
不能.