双倍真的不适合金钱吗?
我总是在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提到的那样实际上更适合。
链接地址: http://www.djcxy.com/p/21371.html上一篇: Is a double really unsuitable for money?
下一篇: Convert floating point number to certain precision, then copy to String