zoukankan      html  css  js  c++  java
  • AutoCAD.Net/C#.Net QQ群:193522571 NCalc 学习笔记

    原文链接:https://segmentfault.com/a/1190000003036617

    简易使用说明
    - 简介
    - 操作符
    - 值
    - 函数
    - 参数
    简单表达式
    Expression e = new Expression("2 + 3 * 5");
    Debug.Assert(17 == e.Evaluate());
    计算 .NET 数据类型
    Debug.Assert(123456 == new Expression("123456").Evaluate()); // integers
    Debug.Assert(new DateTime(2001, 01, 01) == new Expression("#01/01/2001#").Evaluate()); // date and times
    Debug.Assert(123.456 == new Expression("123.456").Evaluate()); // floatinpoint numbers
    Debug.Assert(true == new Expression("true").Evaluate()); // booleans
    Debug.Assert("azerty" == new Expression("'azerty'").Evaluate()); // strings
    处理 System.Math 所支持的函数
    Debug.Assert(0 == new Expression("Sin(0)").Evaluate());
    Debug.Assert(2 == new Expression("Sqrt(4)").Evaluate());
    Debug.Assert(0 == new Expression("Tan(0)").Evaluate());
    计算自定义函数
    Expression e = new Expression("SecretOperation(3, 6)");
    e.EvaluateFunction += delegate(string name, FunctionArgs args)
                          {
                              if (name == "SecretOperation")
                                  args.Result = (int)args.Parameters[0].Evaluate() + (int)args.Parameters[1].Evaluate();
                          };
     
    Debug.Assert(9 == e.Evaluate());
    处理 Unicode 字符
    Debug.Assert("唐衣可俊" == new Expression("'唐衣可俊'").Evaluate());
    Debug.Assert("Hello" == new Expression(@"'u0048u0065u006Cu006Cu006F'"Evaluate());
    Debug.Assert("だ" == new Expression(@"'u3060'").Evaluate());
    Debug.Assert("u0100" == new Expression(@"'u0100'").Evaluate());
    定义参数
    Expression e = new Expression("Round(Pow([Pi], 2) + Pow([Pi2], 2) + [X], 2)");
     
    e.Parameters["Pi2"] = new Expression("Pi * [Pi]");
    e.Parameters["X"] = 10;
     
    e.EvaluateParameter += delegate(string name, ParameterArgs args)
                            {
                              if (name == "Pi")
                              args.Result = 3.14;
                            };
     
    Debug.Assert(117.07 == e.Evaluate());
     
    简介
    NCalc 是一个能够进行表达式计算的一系列程序集( Assembly )。我们主要使用 Expression 类,这个类有一个函数 Evaluate() 能够计算表达式的值。表达式采用字符串形式传入。
    举例:
    Expression e = new Expression("2 * 3");
      object result = e.Evaluate();
    Console.WriteLine(result);
    很简单,创建一个 Expression 对象,通过构造函数传入需要计算的表达式字符串。调用 Evaluate() 方法进行解析,得到计算结果。

    大小写敏感
    NCalc 默认对大小写敏感,如果想要忽略大小写,只需要添加一个参数即可,
    Expression e = new Expression("aBs(-1)", EvaluateOptions.IgnoreCase)
    Debug.Assert(1M, e.Evaluate());
    错误处理
    如果表达式有语法错误,求值会抛出 EvaluationException。
    try
    {
        new Expression("(3 + 2").Evaluate();
    }
    catch(EvaluationException e)
    {
        Console.WriteLine("Error catched: " + e.Message);
    }
    当然,我们也可以在求值之前通过 HasErrors() 函数来检测语法错误。
    Expression e = new Expression("a + b * (");
    if(e.HasErrors())
    {
        Console.WriteLine(e.Error);
    }

    表达式缓冲
    一个 Expression 对象只会被编译一次。因此通过改变参数来重用表达式对象能够提高程序性能。这样每次计算就只需要遍历表达式树就好了。
    实际上,每个编译过的表达式都会缓冲起来,我们完全不需要自己考虑重用表达式。
    使用 CacheEnabled 可以从框架层面更改默认设置。
    Expression.CacheEnabled = false;
    也可以对某个特定的表达式对象进行设置
    Expression e = new Expression("1 + 1", EvaluateOption.NoCache);
     
    运算符
    毋庸置疑,表达式支持各种基本的运算符。各种运算符的优先级由高到低如下:
    原子运算符 (, )
    单目运算符 !, not, -, ~(按位取反)
    幂次运算符 (原文作者遗漏了,他写了位运算符 &, |, ^(xor), <<, >> )
    乘除运算符 *, /, %
    加减运算符 +, -
    关系运算符 =, ==, !=, <>, <, <=, >, >=
    逻辑运算符 or,||,and,&&
    注:感觉上面的优先级并不大靠谱,用之前先试试。
     

    值是代表具体元素的一个终端口令(A value is a terminal token representing a concrete element),它可以是:
    + 整数(Int32)
    + 浮点数(Decimal)(与 Double 相比,有更高的精度和更小的取值范围)
    + 科学计数(Double)
    + 日期(DateTime)
    + 布尔值(bool)
    + 字符串(String)
    + 函数
    + 参数
    整数123
    浮点数1.23
    科学计数1.2e5
    日期#2017/5/1#
    日期用井号包围起来,格式要按照 DateTime 的本地文化(Culture)书写方式写。
    布尔值
    true
    false
    字符串
    用单引号括起来表示字符串
    'hello, tangyikejun!'
    函数
    跟函数调用的用法差不多
    foo(1,'blia')
    参数
    参考参数部分的说明吧,

    2 + x, 2 + [x]
     

    函数

    NCalc 本身已经实现的函数列表如下:

    函数名描述用例用例结果
    Abs 返回绝对值 Abs(-1) 1M
    Acos 返回余弦值对应的角度 Acos(1) 0d
    Asin - - d
    Atan - - d
    Ceiling 向上取整 Ceiling(1.5) 2d
    Cos - - d
    Exp 相当于 e 的 X 次幂 Exp(0) 1d
    Floor 向下取整 Floor(1.5) 1d
    IEEERemainder IEEE 754 标准下的取余操作,具体细节自行百度 IEEERemainder(3, 2) -1d
    Log 以第二个参数为底取对数 Log(1,10) 0d
    Log10 以10为底取对数 Log10(1) 0d
    Max - Max(1,2) 2
    Min - Min(1,2) 1
    Pow - Pow(3,2) 9d
    Round 第二个参数表示保留几位小数,Round 的舍入规则是“四舍六入五成双”,具体的舍入中间值可以在构造 Expression 对象时用 EvaluateOption.RoundAwayFromZero 设定。 Round(3.222,2) 3.22d
    Sign 取符号 Sign(-10) -1
    Sin - - d
    Sqrt 取平方根 Sqrt(4) 2d
    Tan - - d
    Truncate 截取整数部分 Truncate(1.7) 1

    注:结果中的 M 代表 Decimal 类型,d 代表 Double 类型。

    其他通用函数:

    函数名描述用例结果
    in 判断第一个元素是否在后面的一系列值之中 in(1 + 1, 1, 2, 3) true
    if 类似于 expression ? a:b 。根据表达式结果在后两个参数中选择一个返回 if(3 % 2 = 1, 'value is true', 'value is false') 'value is true'
  • 相关阅读:
    写在博客前面
    JavaAPI学习(一):API && String类 && Stringbuffer && StringBuilder
    Java面向对象(七):Object类 & 内部类 & 单例模式
    Java面向对象(六):抽象方法 & 接口 & 递归
    Java面向对象(五):OOP三大特性之多态 — final 关键字
    Java面向对象(四):OOP三大特性之封装与继承
    Java面向对象(三):Java权限修饰符—static关键字
    Java面向对象(二):成员变量—OOP中的内存管理—构造函数
    Java面向对象(一):方法—初识面向对象
    JavaSE学习(六):随机数—简单的排序算法
  • 原文地址:https://www.cnblogs.com/swtool/p/11472638.html
Copyright © 2011-2022 走看看