2010-02-11 63 views
1

这是我的一些数学测试代码,我正在做:C#数字错误驱使我疯狂

为什么C#处理这个不同呢?

EXCEL

分子= = -0.161361101510599 * 10000000 分母= =( - 1 *(100-81.26))*(一百分之千万)

+0

我也尝试过小数 - 没有区别 – 2010-02-11 14:45:07

+2

LOL,excel和完全不符合同一个句子:)如果你想精确算术,使用有理数,而不是浮点数。 – leppie 2010-02-11 14:49:08

+1

当你说“如果我在Excel中这样做”时,你能否澄清一下:你指的是* Excel *还是* VBA *?他们的一些功能有所不同。 – 2010-02-11 14:57:24

回答

3

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

督察:0.161361101510599 != 0.161361102

+0

哇。我错过了那一个! – xan 2010-02-11 14:52:54

+0

好吧 - 使用相同的数字我现在得到0.8610517689999946638207043757M而不是0.861051769000 – 2010-02-11 14:53:23

+1

在这种情况下,IOW意味着“换句话说”,而不是“怀特岛”或“我自己的羊毛” – bobobobo 2010-02-11 14:59:32

4

这是最有可能的数字是如何在Excel中表示对C#所致。在不同的平台上或使用不同的软件进行高精度的artihmatic时,舍入误差/差异是常见的。

编辑:它当然可以是由于不同的数字首先被喂入。去找我复杂的答案吧!

程序员在错过大局,忽视显而易见(好 - 我是...)的情况下是臭名昭着的!

+0

嘿嘿+1为诚恳:) – leppie 2010-02-11 15:02:52

+0

那么,众所周知,编写算法错误分析软件比手工比较数字更容易。我们都是程序员。数字运算是针对电脑操作员的。 (只是为了安全起见:这是为了讽刺:) – zendar 2010-02-11 15:08:49

4

在您对另一个答案发表评论之后,您说您正在获得结果(0.8610517689999946638207043757m)。如果您们就像这样:

Math.Round(0.8610517689999946638207043757m, 12); 

这将输出:0,861051769000

2

没有很多我们谁上的数字计算信任的Excel工作要正确添加2个1位数。我在Mathematica中运行你的计算,通过将它们向右延伸0来给每个小数64位数。这是结果:

0.861051771611526147278548559231590181430096051227321237993596585 

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

+0

Excel通常具有相当高的精确度,IIRC它比'double'好,也许96/128位? – leppie 2010-02-11 15:01:40

+0

从数字p-o-v开始,Excel的真正问题在于,它似乎并未实现IEEE算术或其任何合理的超集。它似乎旨在掩盖试图在计算机上进行真实(实数和真实)算术的恶作剧。这可能很适合它的目标受众,但是为了正确的数字处理,可能很难从中直接得到答案。 – 2010-02-11 15:25:27

1

另一个说明;你可能应该简化你的算术,以减少操作次数。通常,(但不总是)较少的操作在f.p.中得到较好的结果。算术。

val = noiseTerm/(81.26/100 - 1) 

在数学上等同于你的公式,并包含3个操作,而不是你的8尤其是scalingFactor划分出完全,所以它是没有必要的。

1

首先,在大多数情况下,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使用“常规”格式,将该数字四舍五入成12位有效数字。通过更改为上面的格式,您可以强制Excel显示15位精度 - 这是Excel用来显示数字的最大有效位数(在内部,它们具有15位以上的精度,就像C#double类型一样) 。

您可以强制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 ......但据我所知没有办法让Excel显示15位以上的数字。