C#数字错误驱使我疯狂

这是我正在做的一些mathtesting代码:

为什么C#对待这个不同呢?

EXCEL

分子= = – 0.161361101510599 * 10000000分母= =( – 1 *(100-81.26))*(10000000/100)

你的问题是,你正在喂Excel不同的初始值到您的C#代码。 你如何期望他们是相同的?

IOW: 0.161361101510599 != 0.161361102

这很可能是由于excel和C#中的数字是如何表示的。 当在不同的平台上或使用不同的软件进行高精度的艺术处理时,舍入误差/差异是常见的。

编辑:它当然可以是由于不同的数字被喂养在第一位。 去找我复杂的答案!

程序员在错过大局面,忽视显而易见的(好 – 我是…)方面是臭名昭着的!

在您对另一个答案的评论之后,你说你正在获得结果(0.8610517689999946638207043757m)。 如果你像这样四舍五入:

 Math.Round(0.8610517689999946638207043757m, 12); 

它会输出:0,861051769000

我们中很多从事数字计算的人都信任Excel以正确添加2 1位数字。 我在Mathematica中运行你的计算,通过将它们向右延伸0来给出每个小数64位数。 这是结果:

 0.861051771611526147278548559231590181430096051227321237993596585 

在这种情况下,使用C#而不是Excel。 而且,在第二和第三个想法中,在每一种情况下都是用C#而不是用Excel来处理,这些数字计算的不足之处是广为人知和有据可查的。

Excel存储15位有效数字的精度。 阅读文章“ 为什么Excel给我表面上错误的答案? ”。

另一个注意事项; 你可能应该简化你的算术,以减less操作次数。 通常,(但不总是)较less的操作在fpalgorithm中给出更好的结果。

 val = noiseTerm / (81.26/100 - 1) 

在math上等价于你的等式,并包含3个操作,而不是你的8.特别是,scalingFactor完全分开,所以根本没有必要。

首先,在大多数情况下,Excel像C#一样使用双精度浮点运算来进行基本操作。

至于您的具体情况,您的C#代码不匹配您的Excel公式。 试试这个C#代码 – 它使用你的Excel公式:

  static void Calc() { double numerator = -0.161361101510599 * 10000000.0; double denominator = (-1.0 * (100.0 - 81.26)) * (10000000.0 / 100.0); double result = numerator / denominator; Console.WriteLine("result={0}", result); } 

运行这个并注意输出是0.861051768999995。

现在,使用自定义数字格式“0.00000000000000000”在Excel中格式化结果,您将看到Excel正在为您提供与C#相同的结果。 默认情况下,Excel使用“General”格式,将该数字四舍五入为精度达到12位有效数字。 通过更改为上面的格式,您可以强制Excel显示15位精度 – 这是Excel用来显示数字的最大有效位数(在内部,它们具有15位以上的精度,就像C#doubletypes一样) 。

通过运行以下代码,可以强制C#显示15位以上的有效数字(而不是舍入到15位有效数字):

  static void Calc() { double numerator = -0.161361101510599 * 10000000.0; double denominator = (-1.0 * (100.0 - 81.26)) * (10000000.0 / 100.0); double result = numerator / denominator; Console.WriteLine("result={0:R}", result); } 

此代码将输出0.8610517689999948 …但没有办法AFAIK让Excel显示15+数字。