2015-06-22 82 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

如果您需要确切的十进制运算,你应该使用十进制类型[^]代替。