NCalc Expression.Evaluate() 给出了错误的输出

本文关键字:错误 输出 Expression Evaluate NCalc | 更新日期: 2023-09-27 17:57:24

我们有这样的代码

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,尽管这两个表达式都是正确的。

请指教。

NCalc Expression.Evaluate() 给出了错误的输出

使用"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;

我从其他论坛得到了确切的答案:- 这是浮点数存储方式的限制。

使用 float (System.Single) 或 double(System.Double) 时,数字使用二进制格式存储,该格式无法精确表示每个十进制值。您经常会发现,由于最小有效数字的差异,看起来相同的数字不被视为相等。这记录在 MSDN[^] 上。

如果采用表达式 #2 并在常规 C# 代码中对其进行计算,则会看到它仍返回 false。如果使用指定的 R 格式打印结果,你将看到原因:

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

Console.WriteLine("{0:R}", 15617031.48); 15617031.48

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

如果需要精确的十进制

计算,则可能应该改用十进制类型[^]。