【问题标题】:Decimal precision when multiplying乘法时的小数精度
【发布时间】:2013-01-03 13:32:54
【问题描述】:

给定 2 个像这样的值:

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

其中a + b 将始终为1.0m,两个值都只指定到小数点后两位,并且两个值都是>= 0.0m<= 1.0m

对于xab 的所有可能的十进制值,是否保证x == total 始终为真?使用以下计算:

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

或者在某些情况下x == total 只保留小数点后 2 位,但不能超过小数点?

如果ab 可以指定为无限小数位(在Decimal 允许的范围内),但只要a + b = 1.0m 仍然成立,会有什么不同吗?

【问题讨论】:

  • 你是什么意思指定无限小数位0.85m0.8500000000000000m 不一样吗?
  • @Rotem 二进制表示不同;我不确定当你乘法时它是否会导致行为差异。编辑:Apparently not - Trailing zeroes do not affect the value of a Decimal number in arithmetic or comparison operations
  • @Rawling 这个答案引用了 MSDN 的声明,否则:stackoverflow.com/a/1132777/860585
  • @CubeSchrauber 你看了吗?检查底部的 11.0000000000000000000000000000 的示例输出。小数不像双精度/浮点数那样存储,而是使用基数 10,这会产生巨大的差异。
  • @CubeSchrauber 你是认真的吗?!当然它是以二进制形式存储的,因为一切都是(顺便说一句。FF 是十六进制,而不是二进制)。这并没有改变浮点数/双精度数和小数在内部表示的事实。浮点数使用(-1)^s * m * 2^e 表示;这就是为什么它可以精确地表示 0.5 (1 * 2^-1) 但不能表示 0.3。另一方面,小数以 10 为底,使用 (-1)^s * m * 10^e,因此如果 m 和 e 足够精确,我们可以精确表示所有小数,包括 0.3 (3 * 10^-1)。继续阅读IEEE 754

标签: c# .net decimal precision


【解决方案1】:

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

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

来自 MSDN:

Decimal 值类型表示十进制数,范围从 正 79,228,162,514,264,337,593,543,950,335 转负 79,228,162,514,264,337,593,543,950,335。十进制值类型是 适用于需要大量的财务计算 有效的整数和小数位数,并且没有舍入错误。 Decimal 类型不会消除舍入的需要。而是它 最大限度地减少因四舍五入造成的误差。例如下面的代码 产生的结果是 0.9999999999999999999999999999 而不是 1

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

【讨论】:

    【解决方案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 各自的精度无关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多