十进制的准确性

时间:2013-10-18 03:47:45

标签: c# decimal

我使用小数类型进行高精度计算(货币)。

但我今天遇到了这个简单的部门:

1 / (1 / 37)应该再次导致37

http://www.wolframalpha.com/input/?i=1%2F+%281%2F37%29

但是C#给了我: 37.000000000000000000000000037M

我试过这两个: 1m/(1m/37m);Decimal.Divide(1, Decimal.Divide(1, 37))

但两者都产生相同的结果。这种行为是如何解释的?

2 个答案:

答案 0 :(得分:4)

Decimal将值存储为十进制浮点,且精度有限。未精确存储1/37的结果,因为它存储为0.027027027027027027027027027M。真实数字使组027以十进制表示无限期地进行。因此,对于每个可能的数字,您无法获得十进制表示的精确数字。

如果在同一计算中使用Double,则在这种情况下最终结果是正确的(但这并不意味着它总是更好)。

关于该主题的一个好答案是:Difference between decimal, float and double in .NET?

答案 1 :(得分:1)

十进制数据类型的准确度为28-29个有效数字。 因此,您必须了解的是,当您考虑28-29个有效数字时,您仍然不准确。

因此,当您计算(1/37)的十进制值时,您需要注意的是,在此阶段您只能获得28-29位数的精度。例如,当你取2位有效数字时,1/37是0.02,当你取3位有效数字时,得到0.027。想象一下,在每种情况下,您将这些值除以1。在第一种情况下得到50,在第二种情况下得到37.02 ......考虑到28-29位数(十进制),你的准确度为37.000000000000000000000000037。如果你必须得到精确的37,你只需要比小数要多28-29位有效数字。

始终使用最大有效数字进行计算,并使用Math.Round将您的答案四舍五入以获得所需结果。