--- tags: 程式語法, C# --- # [C#] NCalc - 計算以字串表示的數學運算式 ![NCalc] [img-1] 當有一個以字串表示的數學運算式,如:`"2 + 3 * 5"`,要計算結果至少有以下動作需要處理: - 拆字串分出數字和運算符號 - 判斷先乘除後加減 若是用NCalc則能很簡單的得到結果。 ```csharp using NCalc; Expression e = new Expression("2 + 3 * 5"); int result = Convert.ToInt32(e.Evaluate()); ``` ## 支援的運算符號 | 類型 | 符號 | | -------------- | ------------------------------------------- | | 邏輯運算 | `or`, `||`, `and`, `&&` | | 關係運算 | `=`, `==`, `!=`, `<>`, `<`, `<=`, `>`, `>=` | | 加法運算 | `+`, `-` | | 乘法運算 | `*`, `/`, `%` | | 位元運算 | `&`, `|`, `^`, `<<`, `>>` | | 否定與負號 | `!`, `not`, `-`, `~` | | 括號與一般數值 | `(`, `)`, values | ## 支援的資料型態 - 整數 - 浮點數 - 科學記號 - 日期時間 (使用時要用`#`包起來,如:`#2001/01/01#`,否則會變成除法運算) - 布林值 - 字串 (包含unicode字串) ## 支援的函數 - Abs - Acos - Asin - Atan - Ceiling - Cos - Exp - Floor - IEEERemainder - Log - Log10 - Max - Min - Pow - Round - Sign - Sin - Sqrt - Tan - Truncate 以上函數與.NET的[Math類別][link-1]中提供的函數用法相同。 [link-1]: https://docs.microsoft.com/zh-tw/dotnet/api/system.math?view=net-5.0 - in **定義** `in (element, value1, ...)` **說明** 回傳element是否包含在value組中。 **範例** `in(1 + 1, 1, 2, 3)`結果為`true`。 &nbsp; - if **定義** `if (condition, valueTrue, valueFalse)` **說明** condition為true時回傳valueTrue,false時回傳valueFalse。 **範例** `if(3 % 2 = 1, 'correct', 'wrong')`結果為`'correct'`。 &nbsp; - 自訂函數 **範例**:自訂`MyAdd(a, b)`函數做a + b加法運算。 ```csharp Expression e = new Expression("MyAdd(3, 6)"); e.EvaluateFunction += delegate(string name, FunctionArgs args) { if(name == "MyAdd") args.Result = (int)args.Parameters[0].Evaluate() + (int)args.Parameters[1].Evaluate(); }; int result = Convert.ToInt32(e.Evaluate()); ``` ## 支援參數使用 使用時要用`[]`括起來,如:`2 * [x] + 5 * [y]`,x和y即為參數。 ※ 不括起來似乎也能使用。 ### 靜態參數 ```csharp Expression e = new Expression("2 * [x] + 5 * [y]"); e.Parameters["x"] = 5; e.Parameters["y"] = 1; int result = Convert.ToInt32(e.Evaluate()); ``` ### 動態參數 ```csharp Expression e = new Expression("2 * [x] + 5 * [y]"); e.EvaluateParameter += delegate(string name, ParameterArgs args) { if(name == "x") args.Result = 5; else if(name == "y") args.Result = 1; }; int result = Convert.ToInt32(e.Evaluate()); ``` ### 運算式參數 參數除了數值之外,也可以是另一個運算式。 ```csharp Expression e = new Expression("[sub] + 3 * [z]"); Expression sub = new Expression("2 * [x] + 5 * [y]"); e.Parameters["sub"] = sub; e.Parameters["z"] = 2; sub.Parameters["x"] = 5; sub.Parameters["y"] = 1; int result = Convert.ToInt32(e.Evaluate()); ``` --- **參考資料** [NCalc-Edge](https://github.com/pitermarx/NCalc-Edge/wiki) [img-1]: https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEb381oXwD8FsbgFob7bS3I6Yr_ZqvuIY5o4UXMDtgZNcjOKKqlKsGZ4LmlIzTaZy35n-N6q6rlALII3gY1H8ehon_CfJbwgXcP2mITxkUMtKpOQ6d2wEwXyxMatrY9TvVJdWZyqTdLfRMUKFF7pIZ7UTCMagX6vazv8Q6r_7dGLMOShvH7lHemLPRgUYl/s1600/ncalc.png