提问人:Matt Warren 提问时间:1/3/2013 更新时间:1/3/2013 访问量:3117
乘法时的十进制精度
Decimal precision when multiplying
问:
给定 2 个值,如下所示:
decimal a = 0.15m;
decimal b = 0.85m;
Where will always be ,这两个值都只指定为小数点后 2 位,并且两个值都是 和a + b
1.0m
>= 0.0m
<= 1.0m
是否保证对于 和 的所有可能的十进制值始终为真?使用以下计算:x == total
x
a
b
decimal x = 105.99m;
decimal total = (x * a) + (x * b);
还是只有小数点后 2 位,但不超过小数点?x == total
如果并且可以指定为无限的小数位(尽可能允许),但只要仍然成立,会有什么区别吗?a
b
Decimal
a + b = 1.0m
答:
十进制存储为表示小数位置的数字 10 的符号、整数和整数指数。只要数字的整数部分(例如 105.99 中的 105)不够大,那么 a + b 将永远等于 1。您的等式 (x * a) + (x * b) 的结果将始终具有正确的小数点后四位值。
与浮点数和双精度值不同,精度不会丢失到数据类型的大小(128 位)
来自 MSDN:
Decimal value 类型表示范围为 正数 79,228,162,514,264,337,593,543,950,335 改为负数 79,228,162,514,264,337,593,543,950,335。 十进制值类型为 适用于需要大量 显著的整数和小数数字,无舍入误差。 Decimal 类型并不能消除舍入的需要。相反,它 最大限度地减少由于舍入而导致的错误。例如,以下代码 产生的结果为 0.999999999999999999999999999999999 而不是 1
decimal dividend = Decimal.One;
decimal divisor = 3;
// The following displays 0.9999999999999999999999999999 to the console
Console.WriteLine(dividend/divisor * divisor);
CLR 中的最大精度为 29 位有效数字。当您使用这种精度时,您实际上是在谈论近似值,尤其是在执行乘法运算时,因为这需要 CLR 必须能够处理的中间结果(另请参见 http://msdn.microsoft.com/en-us/library/364x0z75.aspx)。decimal
如果 x 有 2 个有效数字,比如说 a 有 20 个有效数字,那么 x * a 的最小精度已经为 22 位,中间结果可能需要更多精度。
如果 x 总是只有 2 个有效数字,并且您可以将 a 和 b 中的有效数字数量保持在足够低的水平(比如说,22 位数字——相当不错,并且可能离 27 足够远以处理舍入错误),那么我认为 (x * a) + (x * b) 应该始终是一个非常精确的计算。
最后,a+b是否总是构成1.0m与a和b的各自精度无关。
评论
0.85m
0.8500000000000000m
Trailing zeroes do not affect the value of a Decimal number in arithmetic or comparison operations
1
1.0000000000000000000000000000
FF
(-1)^s * m * 2^e
1 * 2^-1
(-1)^s * m * 10^e
3 * 10^-1