仿真Excel数字精度C#.NET

Excel精确系统

Excel具有数字精度的IEEE 754规范的修改版本。 有关Excel如何计算的更多信息可以在这里find。

总结:

  • 数字只存储在15个主要数字中。
  • 在任何计算之前,Excel试图将该数字表示为2的幂(因为它是二进制表示)
  • 如果数不是2的简单幂,则它使用几何级数来找出最接近的二进制数。
  • 如果这个数字真的很小,Excel表示它是一个简单的2的幂。

问题

其他语言,在我的情况下, C#.NET ,以不同的方式实现数字精度。 所以,当你试图模拟一个电子表格,你最终会得到一些精度不匹配。

打开Excel并在任何单元格中插入此公式:

=1+1/9000-1. 

那么你会注意到结果与下面公式得到的结果不一样:

 =1/9000 

我不想改变Excel的这种行为,我只是想模仿它。

现在在C#中创build一个简单的程序,并使用Decimal数进行相同的计算。 我使用小数来表示数字。 但它可能是我们Float的两倍,结果是一样的。

 decimal result = 1.0M + 1.0M / 9000.0M - 1.0M; Console.WriteLine(result.ToString("N30")); 

有没有什么办法可以模拟Excel的数字精度。 这样我可以得到与Excel相同的结果?

编辑

正如@DStanley所提到的,使用double可以解决上面的例子,但是对于其他情况仍然不起作用,例如:

Excel中:

 =1+0.000000000000001665280326829110-1 0.000000000000000000000000000000 

C#:

 double result = 1.0 + 0.000000000000001665280326829110 - 1.0; Console.WriteLine(result.ToString("N30")); 0.000000000000001554312234475220 

如果你想模拟浮点math,那么使用double而不是decimaldecimal被devise为以速度为代价提供更准确的基10表示。 如果在C#中使用double ,则得到的结果与Excel相同(至less对于您的示例而言,可能会有其他边界情况的行为不同):

C#:

 double result = 1.0 + 1.0 / 9000.0 - 1.0; Console.WriteLine(result.ToString("N30")); 0.000111111111111173000000000000 

Excel中:

 =1+1/9000-1 0.000111111111111173000000000000