模拟Excel数字精度C#.NET

时间:2015-09-15 21:57:55

标签: c# asp.net-mvc excel vba math

Excel Precision系统

Excel具有针对数字精度的IEEE 754规范的修改版本。有关Excel如何进行计算的更多信息,请here

汇总:

  • 数字只存储了15位领导人物。
  • 在进行任何计算之前,Excel会尝试将数字表示为2的幂(因为它的二进制表示)
  • 如果数字不是2的简单幂,则使用几何级数来找到二进制表示的最接近的数字。
  • 如果数字非常小,则Excel将其表示为2的简单幂。

问题

在我的情况下,其他语言 C#.NET ,以不同的方式实现数字精度。 因此,当您尝试模拟电子表格时,最终会出现一些精确度不匹配。

实施例

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

=1+1/9000-1.

然后您会注意到结果与通过以下公式获得的结果不同:

=1/9000

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

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

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

问题

有没有什么方法可以让C#模仿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

1 个答案:

答案 0 :(得分:1)

如果要模拟浮点数学,请使用double代替decimaldecimal旨在以牺牲速度为代价提供更准确的基数10表示。如果在C#中使用double,则会得到与Excel相同的结果(至少对于您的示例 - 可能存在其他行为不同的边缘情况):

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