小数的准确性

本文关键字:准确性 小数 | 更新日期: 2023-09-27 18:36:03

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

但是我今天遇到了这个简单的划分:

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))

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

小数的准确性

Decimal

值存储为精度有限的十进制浮点数。1/37 的结果没有预先存储,因为它存储为 0.027027027027027027027027027027M。真正的数字使组 027 以十进制表示无限期。因此,您无法为每个可能的数字获取十进制表示形式的精确数字。

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

关于该主题的一个很好的答案是:.NET 中的十进制、浮点数和双精度之间的区别?

十进制数据类型的精度为 28-29 位有效数字。所以你必须明白的是,当你考虑28-29个有效数字时,你仍然不准确。

因此,当您计算 (1/37) 的十进制值时,您必须注意的是,在此阶段您只能获得 28-29 位的精度。 例如,当您取 2 位有效数字时,1/37 为 0.02,当您采用 3 位有效数字时为 0.027。假设您在每种情况下都用这些值除以 1。在第一种情况下,你得到50,在第二种情况下,你得到37.02...考虑28-29位数字(十进制)会让你达到37.00000000000000000000000000037的精度。如果你必须得到一个精确的 37,你只需要比十进制提供的超过 28-29 位有效数字。

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