乘法时的十进制精度

时间:2013-01-03 13:32:54

标签: c# .net decimal precision

给出2个这样的值:

decimal a = 0.15m;
decimal b = 0.85m;

a + b始终为1.0m,两个值仅指定为2位小数,且值均为>= 0.0m<= 1.0m

对于x == totalxa的所有可能的十进制值,

保证 b将始终为真吗?使用下面的计算:

decimal x = 105.99m;
decimal total = (x * a) + (x * b);

或者是否有x == total只有2位小数,但不超过该位数的情况?

如果可以将ab指定为无限小数位(尽管Decimal允许),但是只要a + b = 1.0m仍然有效,这会有什么不同吗? ?

2 个答案:

答案 0 :(得分:4)

十进制存储为表示小数位数的数字10的符号,整数和整数指数。只要数字的整数部分(例如105中的105)不够大,那么a + b将始终等于1。你的等式(x * a)+(x * b)的结果将始终具有四位小数的正确值。

与float和double不同,精度不会丢失到数据类型的大小(128位)

来自MSDN:

  

十进制值类型表示范围从的十进制数   为负数为79,228,162,514,264,337,593,543,950,335   79,228,162,514,264,337,593,543,950,335。 Decimal值类型是   适用于需要大量资金的财务计算   显着的积分和小数位数,没有舍入误差。   Decimal类型不会消除舍入的需要。相反,它   最小化由于舍入引起的错误。例如,以下代码   产生的结果为0.9999999999999999999999999999而不是1

decimal dividend = Decimal.One;
decimal divisor = 3;
// The following displays 0.9999999999999999999999999999 to the console
Console.WriteLine(dividend/divisor * divisor);

答案 1 :(得分:2)

CLR中decimal的最大精度为29位有效数字。当你使用那种精度时,你真的在​​谈论近似,特别是如果你进行乘法,因为这需要CLR必须能够处理的中间结果(参见http://msdn.microsoft.com/en-us/library/364x0z75.aspx)。

如果您的x有2位有效数字,例如a,有20位有效数字,则x * a的最小精度为22位,中间结果可能需要更多。

如果x总是只有2位有效数字,你可以保持a和b中有效数字的位数足够低(比方说22位数 - 非常好,可能远远超过27来处理舍入错误),那么我想(x * a)+(x * b)应该是一个非常精确的计算。

最后,a + b总是构成1.0m与a和b的个体精度无关。