using NCalc; using System.Text.RegularExpressions; namespace Alchemy.Core.Extensions { public static class NCalcExtensions { /// /// 注册自定义函数 /// /// /// public static void AddExtraFunction(this Expression expression) { expression.EvaluateFunction += (name, args) => { object paramX = args.Parameters[0].Evaluate(); double doubleParamX = paramX.ToString().ToDouble(); object paramY = null; double doubleParamY = 0; if (args.Parameters.Count() > 1) { paramY = args.Parameters[1].Evaluate(); doubleParamY = paramY.ToString().ToDouble(); } switch (name.ToLower()) { // 阶乘函数 case "fact": int number = paramX.ToString().ToInt(); args.Result = CalculateFactorial(number); break; // 反三角函数(返回弧度) case "sin": args.Result = Math.Sin(paramX.ToString().ToDouble()); break; case "cos": args.Result = Math.Cos(paramX.ToString().ToDouble()); break; case "tan": args.Result = Math.Tan(paramX.ToString().ToDouble()); break; // 反三角函数(返回弧度) case "arcsin": case "asin": if (doubleParamX < -1 || doubleParamX > 1) throw new ArgumentException("反正弦 x∈[-1,1]"); args.Result = Math.Asin(paramX.ToString().ToDouble()); break; case "arccos": case "acos": if (doubleParamX < -1 || doubleParamX > 1) throw new ArgumentException("反余弦 x∈[-1,1]"); args.Result = Math.Acos(paramX.ToString().ToDouble()); break; case "arctan": case "atan": args.Result = Math.Atan(paramX.ToString().ToDouble()); break; // 角度/弧度转换函数 case "rad": // 角度转弧度 args.Result = paramX.ToString().ToDouble() * Math.PI / 180; break; //case "deg": // 弧度转角度 // args.Result = Convert.ToDouble(param) * 180 / Math.PI; // break; // 平方根函数 case "sqrt": if (doubleParamX < 0) throw new ArgumentException("平方根 x∈[0,+∞)"); args.Result = Math.Sqrt(doubleParamX); break; // 次幂函数 case "pow": args.Result = Math.Pow(doubleParamX, doubleParamY); break; } }; } /// /// 注册常量 /// /// public static void AddExtraConst(this Expression expression) { expression.Parameters["e"] = Math.E; // 自然常数 e expression.Parameters["pi"] = Math.PI; // 圆周率 π } public static object Evaluate(this string strFormula, string strAngleMode) { strFormula = Regex.Replace( strFormula, @"(\d+)\!", "fact($1)"); strFormula = Regex.Replace( strFormula, @"([^\(\)^]+)\^([^\(\)^]+)", "pow($1,$2)"); if (strAngleMode.Equals("deg")) { strFormula = Regex.Replace( strFormula, @"(?