math-engineGo 實現(xiàn)的數(shù)學表達式解析計算引擎
使用 Go 實現(xiàn)的數(shù)學表達式解析計算引擎庫,無任何依賴,相對比較完整的完成了數(shù)學表達式解析執(zhí)行,包括詞法分析、語法分析、構(gòu)建AST、運行。
能夠處理的表達式樣例:
1+127-21+(3-4)*6/2.5(88+(1+8)*6)/2+99123_345_456 * 1.5 - 2 ^ 4-4 * 6 + 2e2 - 1.6e-3sin(pi/2)+cos(45-45*1)+tan(pi/4)99+abs(-1)-ceil(88.8)+floor(88.8)max(min(2^3, 3^2), 10*1.5-7)
Demo
Method Support
| symbol | explanation | e.g. |
|---|---|---|
+ |
加,plus | 1+2 = 3 |
- |
減,sub | 8-3.5 = 4.5 |
* |
乘,multiply | 2*3 = 6 |
/ |
除,division | 5/2 = 2.5 |
% |
取余,remainder | 5%2 = 1 |
^ |
整數(shù)次方,integer power | 2^3 = 8, 3^2 = 9 |
e |
科學計數(shù)法,E-notation | 1.2e3 = 1200,1.2e-2 = 0.012 |
() |
括號,brackets | (2+3)*4 = 20 |
_ |
數(shù)字分隔符,number separator | 123_456_789 = 123456789 |
pi |
π | pi = 3.141592653589793 |
sin(x) |
正弦函數(shù),sine | sin(pi/2) = 1 |
cos(x) |
余弦函數(shù),cosine | cos(0) = 1 |
tan(x) |
正切函數(shù),tangent | tan(pi/4) = 1 |
cot(x) |
余切函數(shù),cotangent | cot(pi/4) = 1 |
sec(x) |
正割函數(shù),secant | sec(0) = 1 |
csc(x) |
余割函數(shù),cosecant | csc(pi/2) = 1 |
abs(x) |
絕對值,absolute value | abs(-6) = 6 |
ceil(x) |
向上取整 | ceil(4.2) = 5 |
floor(x) |
向下取整 | floor(4.8) = 4 |
round(x) |
四舍五入取整 | round(4.4) = 4, round(4.5) = 5 |
sqrt(x) |
平方根,square root | sqrt(4) = 2 |
cbrt(x) |
立方根,cube root | cbrt(27) = 3 |
max(x, y) |
x, y 中的較大值 | max(2, 3) = 3 |
min(x, y) |
x, y 中的較小值 | min(2, 3) = 2 |
Usage
你可以直接引用該庫嵌入到自己的程序中:
go get -u github.com/dengsgo/math-engine
在代碼中引入:
import "github.com/dengsgo/math-engine/engine"
e.g. 1 直接調(diào)用解析執(zhí)行函數(shù) :
import "github.com/dengsgo/math-engine/engine"
func main() {
s := "1 + 2 * 6 / 4 + (456 - 8 * 9.2) - (2 + 4 ^ 5)"
// call top level function
r, err := engine.ParseAndExec(s)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s = %v", s, r)
}
e.g. 2 依次調(diào)用函數(shù),手動執(zhí)行 :
import "github.com/dengsgo/math-engine/engine"
func main() {
s := "1 + 2 * 6 / 4 + (456 - 8 * 9.2) - (2 + 4 ^ 5)"
exec(s)
}
// call engine
// one by one
func exec(exp string) {
// input text -> []token
toks, err := engine.Parse(exp)
if err != nil {
fmt.Println("ERROR: " + err.Error())
return
}
// []token -> AST Tree
ast := engine.NewAST(toks, exp)
if ast.Err != nil {
fmt.Println("ERROR: " + ast.Err.Error())
return
}
// AST builder
ar := ast.ParseExpression()
if ast.Err != nil {
fmt.Println("ERROR: " + ast.Err.Error())
return
}
fmt.Printf("ExprAST: %+v\n", ar)
// AST traversal -> result
r := engine.ExprASTResult(ar)
fmt.Println("progressing ...\t", r)
fmt.Printf("%s = %v\n", exp, r)
}
編譯運行,應(yīng)該可以看到如下輸出:
ExprAST: {Op:- Lhs:{Op:+ Lhs:{Op:+ Lhs:{Val:1} Rhs:{Op:/ Lhs:{Op:* Lhs:{Val:2} Rhs:{Val:6}} Rhs:{Val:4}}} Rhs:{Op:- Lhs:{Val:456} Rhs:{Op:* Lhs:{Val:8} Rhs:{Val:9.2}}}} Rhs:{Op:+ Lhs:{Val:2} Rhs:{Op:^ Lhs:{Val:4} Rhs:{Val:5}}}}
progressing ... -639.6
1+2*6/4+(456-8*9.2)-(2+4^5) = -639.6
TrigonometricMode
三角函數(shù)的參數(shù)類型默認為弧度RadianMode,e.g. sin(pi/2) = 1.
你可以通過設(shè)置 TrigonometricMode 調(diào)整參數(shù)類型,可選 弧度RadianMode、角度AngleMode,e.g. :
import "github.com/dengsgo/math-engine/engine"
func main() {
s := "1 + sin(90)"
engine.TrigonometricMode = engine.AngleMode
engine.ParseAndExec(s) // will return 2, nil
s = "1 + sin(pi/2)"
engine.TrigonometricMode = engine.RadianMode
engine.ParseAndExec(s) // will return 2, nil
}
Document
godoc.org/github.com/dengsgo/math-engine/engine
Compile
go version 1.12
# Compile Demo go test go build ./math-engine
也可以直接下載已編譯好的二進制文件,直接運行:
實現(xiàn)細節(jié)
請閱讀我的博客文章:用 Go 實現(xiàn)一個完整的數(shù)學表達式計算引擎
TODO
已實現(xiàn)
- 加
+ - 減
- - 乘
* - 除
/ - 取余
% - 整數(shù)次方
^ - 科學計數(shù)法 e.g.
1.2e7、1.2e-7 - 括號
() - 混合運算 e.g.
1+2*6/4+(456-8*9.2)-(2+4^5)*2e3+1.2e-2 - 友好的長數(shù)字 e.g.
123_456_789 - 三角函數(shù) e.g.
sin, cos, tan, cot, sec, csc - 常量 pi
- 輔助函數(shù) e.g.
abs, ceil, floor, sqrt, cbrt - 友好的錯誤消息 e.g.
input /> 123+89-0.0.9
ERROR: strconv.ParseFloat: parsing "0.0.9": invalid syntax
want '(' or '0-9' but get '0.0.9'
------------
123+89-0.0.9
^
------------
待實現(xiàn)
- 精確浮點計算
- 更多輔助函數(shù)
評論
圖片
表情
