2010-02-11 84 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位以上的數字。