关于浮点:在.NET中,如何在小数和双精度之间进行选择Decimal and Double

In .net, how do I choose between a Decimal and a Double

前几天我们在工作中讨论过这个问题,我希望有一个堆积如山的问题,我会指给大家看。

  • DoubleDecimal有什么区别?
  • 什么时候(在什么情况下)应该始终使用Double
  • 什么时候(在什么情况下)应该始终使用Decimal
  • 在不属于上述两个阵营之一的情况下,需要考虑哪些驱动因素?

有很多问题与这个问题重叠,但他们往往是在问某个人在特定情况下应该做什么,而不是在一般情况下如何决定。


我通常会考虑自然数量和人工数量。

自然量是指重量、高度和时间。这些绝对不会被精确测量,也很少有绝对精确算术的概念:你一般不应该把高度加起来,然后确保结果和预期的一样。这种数量使用double。双打的范围很大,但精度有限,而且速度也非常快。

主要的人工数量是金钱。有一件事是"正好10.52美元",如果你加上48美分,你会得到11美元。这种数量使用decimal。理由:考虑到这是人为的开始,涉及的数字也是人为的,旨在满足人类的需要-这意味着他们自然地表达在基数10。使存储表示与人工表示匹配。decimal没有double的范围,但大多数人工量也不需要这个额外的范围。它也比double慢,但我个人有一个银行账户,它给了我一个正确的答案,比一个错误的答案慢得多。

有关更多信息,我有关于.NET二进制浮点类型和.NET十进制类型的文章。(请注意,decimal也是一种浮点类型,但所讨论的"点"是小数点,而不是二进制点。)


如果你想保持真正的精度,就用小数点。

如果要比较值,请保留小数。

如果你用双刀做这个

1
? ctype(1.0, Double ) / 3

你会得到

0.33333333333333331

如果你用小数来做这个

1
? ctype(1.0, Decimal ) /3

你会得到

0.3333333333333333333333333333D

还有一个例子,极端的例子;

1
2
  decimal dec = new decimal(1, 1, 1, false, 28);
  var dou = (double)dec;

会产生这样的结果,双精度会损失一些精度。

? dou
0.0000000018446744078004519
? dec
0.0000000018446744078004518913D

最后,

double=近似值

十进制=实数


SQL Server它还值得一提的是,SQL Server中的decimal映射到.NET框架中的decimal和nullable decimal。而在SQL Server中,float映射为double和nullable double。以防万一你最终会遇到一个数据库应用。

甲骨文公司我不再使用Oracle,正如您在我的配置文件信息中看到的那样:),但是对于那些使用Oracle的人,这里有一篇msdn文章,它映射了Oracle数据类型:

http://msdn.microsoft.com/en-us/library/yk72thhd(vs.80).aspx