---
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`。
- if
**定義**
`if (condition, valueTrue, valueFalse)`
**說明**
condition為true時回傳valueTrue,false時回傳valueFalse。
**範例**
`if(3 % 2 = 1, 'correct', 'wrong')`結果為`'correct'`。
- 自訂函數
**範例**:自訂`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