2015-06-22 100 views
0

我們有代碼等NCalc Expression.Evaluate()給出錯誤的輸出

ncalcFormula = "[OD1000]=[OD1100]+[OD1200]+[OD1350]+[OD1450]"  
var expression = new Expression(ncalcFormula); 

foreach (FormulaParameter fp in parsedParameters) 
{ 
    expression.Parameters[fp.QuestionKey] = fp.Value; 
}  
object res = expression.Evaluate(); 

原始表達式: - [OD1000] = [OD1100] + [OD1200] + [OD1350] + [OD1450]

在稱爲解析表達後的評估之後: - ((OD1000))=(((([OD1100])+([OD1200])+([OD1350])+([OD1450]))

通過添加參數值如下

1)9.33 = 2.25 + 3.25 + 1.5 + 2.33

2)15617031.48 15226149.36 = + 166208.00 + 0.00 + 224674.12

評價1)之後將返回true和2)雖然兩種表達是正確的將返回false。

請建議。

+0

會員爲期4年。這是關於你學習如何在一個問題中設置自己的代碼格式的時候http://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks – weston

+1

這看起來像我這樣的另一個「浮動點數不起作用「的問題。 – spender

回答

0

使用「equlas」運算符比較浮點值是一個糟糕的主意,因爲計算的結果已被安裝到浮點表示。爲了正確執行比較,您需要指定容差,即結果可能與預期值有多大差異。我重寫了一下你的公式,以增加一些「寬容」。

 var ncalcFormula = "Abs([OD1000]-([OD1100]+[OD1200]+[OD1350]+[OD1450])) < 0.00001";  
     var expression = new Expression(ncalcFormula); 
     expression.Parameters["OD1000"] = 15617031.48; 
     expression.Parameters["OD1100"] = 15226149.36; 
     expression.Parameters["OD1200"] = 166208.00; 
     expression.Parameters["OD1350"] = 0.00; 
     expression.Parameters["OD1450"] = 224674.12; 
0

我從其他論壇得到了確切答案: - 這是如何存儲浮點數的限制。

當使用浮子(System.Single)或雙(System.Double),數量也使用二進制格式,它不能精確代表每十進制值存儲。由於其最低有效位數的差異,您會經常發現顯示相同的數字並不相同。這是記錄在MSDN [^]。

如果您使用#2表達式並在常規C#代碼中對其進行評估,則會看到它仍然返回false。如果使用指定的R格式打印結果,您將看到原因:

Console.WriteLine(15617031.48 == 15226149.36 + 166208.00 + 0.00 + 224674.12); //假

Console.WriteLine( 「{0:R}」,15617031.48); // 15617031.48

Console.WriteLine( 「{0:R}」,15226149.36 + 166208.00 + 0.00 + 224674.12); // 15617031.479999999

如果您需要確切的十進制運算,你應該使用十進制類型[^]代替。