{"id":13694418,"url":"https://github.com/dengsgo/math-engine","last_synced_at":"2026-01-03T06:04:40.596Z","repository":{"id":41199627,"uuid":"194256013","full_name":"dengsgo/math-engine","owner":"dengsgo","description":"Mathematical expression parsing and calculation engine library.  数学表达式解析计算引擎库","archived":false,"fork":false,"pushed_at":"2023-08-23T15:44:25.000Z","size":64,"stargazers_count":309,"open_issues_count":4,"forks_count":78,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-08-03T17:19:51.634Z","etag":null,"topics":["ast","engine","expression","go","lib","library","math","mathematical","vendor"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dengsgo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-28T10:34:47.000Z","updated_at":"2024-07-25T02:47:01.000Z","dependencies_parsed_at":"2024-06-18T14:06:59.592Z","dependency_job_id":"3dc6c6b3-cbf3-49ac-ac4e-75b6010bbfa7","html_url":"https://github.com/dengsgo/math-engine","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dengsgo%2Fmath-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dengsgo%2Fmath-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dengsgo%2Fmath-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dengsgo%2Fmath-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dengsgo","download_url":"https://codeload.github.com/dengsgo/math-engine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224346585,"owners_count":17296245,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ast","engine","expression","go","lib","library","math","mathematical","vendor"],"created_at":"2024-08-02T17:01:31.521Z","updated_at":"2026-01-03T06:04:40.518Z","avatar_url":"https://github.com/dengsgo.png","language":"Go","readme":"## Math-Engine  \n\n[![Actions](https://github.com/dengsgo/math-engine/workflows/Go/badge.svg)](https://github.com/dengsgo/math-engine/actions)  [![Go Report Card](https://goreportcard.com/badge/github.com/dengsgo/math-engine)](https://goreportcard.com/report/github.com/dengsgo/math-engine)  [![godoc.org](https://godoc.org/github.com/dengsgo/math-engine/engine?status.svg)](https://godoc.org/github.com/dengsgo/math-engine/engine)  [![Goproxy.cn](https://goproxy.cn/stats/github.com/dengsgo/math-engine/badges/download-count.svg)](https://goproxy.cn)\n\n使用 Go 实现的数学表达式解析计算引擎库，它小巧，无任何依赖，具有扩展性(比如可以注册自己的函数到引擎中)，比较完整的完成了数学表达式解析执行，包括词法分析、语法分析、构建AST、运行。  \n\n`go get -u github.com/dengsgo/math-engine`  \n\n能够处理的表达式样例：  \n- `1+127-21+(3-4)*6/2.5`  \n- `(88+(1+8)*6)/2+99`  \n- `123_345_456 * 1.5 - 2 ^ 4`  \n- `-4 * 6 + 2e2 - 1.6e-3`  \n- `sin(pi/2)+cos(45-45*1)+tan(pi/4)`  \n- `99+abs(-1)-ceil(88.8)+floor(88.8)`  \n- `max(min(2^3, 3^2), 10*1.5-7)`  \n- `double(6) + 3` , `double`是一个自定义的函数  \n\n### Demo\n\n[![asciicast](https://asciinema.org/a/276195.svg)](https://asciinema.org/a/276195)\n\n## Method Support\n\n| symbol      | explanation                  | e.g.                                  |\n| ----------- | ---------------------------- | ------------------------------------- |\n| `+`         | 加，plus                     | 1+2 = 3                               |\n| `-`         | 减，sub                      | 8-3.5 = 4.5                           |\n| `*`         | 乘，multiply                 | 2*3 = 6                               |\n| `/`         | 除，division                 | 5/2 = 2.5                             |\n| `%`         | 取余，remainder              | 5%2 = 1                               |\n| `^`         | 整数次方，integer power      | 2^3 = 8, 3^2 = 9                      |\n| `e`         | 科学计数法，E-notation       | 1.2e3 = 1.2e+3 = 1200，1.2e-2 = 0.012 |\n| `()`        | 括号，brackets               | (2+3)*4 = 20                          |\n| `_`         | 数字分隔符，number separator | 123_456_789 = 123456789               |\n| `pi`        | π                            | pi = 3.141592653589793                |\n| `sin(x)`    | 正弦函数，sine               | sin(pi/2) = 1                         |\n| `cos(x)`    | 余弦函数，cosine             | cos(0) = 1                            |\n| `tan(x)`    | 正切函数，tangent            | tan(pi/4) = 1                         |\n| `cot(x)`    | 余切函数，cotangent          | cot(pi/4) = 1                         |\n| `sec(x)`    | 正割函数，secant             | sec(0) = 1                            |\n| `csc(x)`    | 余割函数，cosecant           | csc(pi/2) = 1                         |\n| `abs(x)`    | 绝对值，absolute value       | abs(-6) = 6                           |\n| `ceil(x)`   | 向上取整                     | ceil(4.2) = 5                         |\n| `floor(x)`  | 向下取整                     | floor(4.8) = 4                        |\n| `round(x)`  | 四舍五入取整                 | round(4.4) = 4, round(4.5) = 5        |\n| `sqrt(x)`   | 平方根，square root          | sqrt(4) = abs(sqrt(4)) = 2            |\n| `cbrt(x)`   | 立方根，cube root            | cbrt(27) = 3                          |\n| `max(x, ...)` | 参数中的较大值              | max(1)=1,max(2,3)=3,max(4,8,6,8,10)=10 |\n| `min(x, ...)` | 参数中的较小值              | min(1)=1,min(2,3)=2,max(4,8,6,8,10)=4 |\n| `noerr(x)`  | 计算 x 出错时返回 0          | noerr(1 / 1)  = 1, noerr( 1/ 0 ) = 0  |\n| `double(x)`  | 返回 x 的双倍值，这是一个自定义的函数示例，你可以注册任意的自定义函数到引擎中  | double(6) = 12  |\n\n\n## Usage  \n\n你可以直接引用该库嵌入到自己的程序中：  \n```bash\ngo get -u github.com/dengsgo/math-engine\n```\n在代码中引入：  \n```go\nimport \"github.com/dengsgo/math-engine/engine\"\n```\ne.g. 1 常规用法： 直接调用解析执行函数 :\n\n```go\nimport \"github.com/dengsgo/math-engine/engine\"\n\nfunc main() {\n  s := \"1 + 2 * 6 / 4 + (456 - 8 * 9.2) - (2 + 4 ^ 5)\"\n  // call top level function\n  r, err := engine.ParseAndExec(s)\n  if err != nil {\n    fmt.Println(err)\n  }\n  fmt.Printf(\"%s = %v\", s, r)\n}\n```\n\n\n\ne.g. 2 高级用法： 依次调用函数，手动执行 :  \n\n```go\nimport \"github.com/dengsgo/math-engine/engine\"\n\nfunc main() {\n\ts := \"1 + 2 * 6 / 4 + (456 - 8 * 9.2) - (2 + 4 ^ 5)\"\n\texec(s)\n}\n\n// call engine\n// one by one\nfunc exec(exp string) {\n\t// input text -\u003e []token\n\ttoks, err := engine.Parse(exp)\n\tif err != nil {\n\t\tfmt.Println(\"ERROR: \" + err.Error())\n\t\treturn\n\t}\n\t// []token -\u003e AST Tree\n\tast := engine.NewAST(toks, exp)\n\tif ast.Err != nil {\n\t\tfmt.Println(\"ERROR: \" + ast.Err.Error())\n\t\treturn\n\t}\n\t// AST builder\n\tar := ast.ParseExpression()\n\tif ast.Err != nil {\n\t\tfmt.Println(\"ERROR: \" + ast.Err.Error())\n\t\treturn\n\t}\n\tfmt.Printf(\"ExprAST: %+v\\n\", ar)\n\t// AST traversal -\u003e result\n\tr := engine.ExprASTResult(ar)\n\tfmt.Println(\"progressing ...\\t\", r)\n\tfmt.Printf(\"%s = %v\\n\", exp, r)\n}\n```\n编译运行，应该可以看到如下输出：  \n```bash\nExprAST: {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}}}}\nprogressing ...  -639.6\n1+2*6/4+(456-8*9.2)-(2+4^5) = -639.6\n```\n\n## TrigonometricMode\n\n三角函数的参数类型默认为弧度`RadianMode`，e.g. `sin(pi/2) = 1`.\n\n你可以通过设置 `TrigonometricMode` 调整参数类型，可选 弧度`RadianMode`、角度`AngleMode`，e.g. :\n\n```go\nimport \"github.com/dengsgo/math-engine/engine\"\n\nfunc main() {\n  s := \"1 + sin(90)\"\n  engine.TrigonometricMode = engine.AngleMode\n  engine.ParseAndExec(s) // will return 2, nil\n  s = \"1 + sin(pi/2)\"\n  engine.TrigonometricMode = engine.RadianMode\n  engine.ParseAndExec(s) // will return 2, nil\n}\n```\n\n## Register Function\n\n`math-engine` 提供了自定义函数注册到引擎的能力。你可以把常用的函数注册到引擎中，然后就能像内置函数一样在输入的数学表达式中使用。\n\ne.g \n\n```go\n  // RegFunction is Top level function\n  // the same function name only needs to be registered once.\n  // double is register function name.\n  // 1 is a number of parameter signatures. should be -1, 0, or a positive integer\n  // func(expr ...engine.ExprAST) float64 is your function.\n  engine.RegFunction(\"double\", 1, func(expr ...engine.ExprAST) float64 {\n    // when argc \u003e 0，you can use the index value directly according to the number of parameters\n    // without worrying about crossing the boundary.\n    // use ExprASTResult to get the result of the ExprAST structure.\n    return engine.ExprASTResult(expr[0]) * 2\n  })\n```\n\n然后你就可以在输入的表达式中使用这个函数 `double`:\n\n```go \n//exp := \"double(6) + 2\"\nr, err := engine.ParseAndExec(\"double(6) + 2\")\nif err != nil {\n  panic(err)\n}\nfmt.Printf(\"double(6) + 2 = %f\\n\", r) // will print ： double(6) + 2 = 14.000000\n```\n\n注意事项：\n- 注册的函数名只能是英文字母和数字，且必须英文字母开头（区分大小写）;\n- 每一个函数名只能且只需注册一次；\n- 注册的函数逻辑中如果有 panic ，需要程序自己捕获处理;  \n- argc=-1，即该函数的参数是可变的，expr 的长度需要开发者自行逻辑判断处理；\n\n## Compile    \n\ngo version 1.12  \n```go\n# Compile Demo\ngo test\ngo build\n./math-engine\n```\n\n也可以直接下载已编译好的二进制文件，直接运行：  \n\n[Github Releases](https://github.com/dengsgo/math-engine/releases)  \n\n## 实现细节    \n\n请阅读我的博客文章：[用 Go 实现一个完整的数学表达式计算引擎](https://www.yoytang.com/math-expression-engine.html)  \n\n## TODO  \n### 已实现  \n\n- [x] 加 `+`  \n- [x] 减 `-`  \n- [x] 乘 `*`  \n- [x] 除 `/`  \n- [x] 取余 `%`  \n- [x] 整数次方 `^`  \n- [x] 科学计数法 e.g. `1.2e7`、  `1.2e-7`\n- [x] 括号 `()`  \n- [x] 混合运算 e.g. `1+2*6/4+(456-8*9.2)-(2+4^5)*2e3+1.2e-2`  \n- [x] 友好的长数字 e.g. `123_456_789`  \n- [x] 三角函数 e.g. `sin, cos, tan, cot, sec, csc`\n- [x] 常量 pi\n- [x] 辅助函数 e.g. `abs, ceil, floor, sqrt, cbrt, max, min, noerr`\n- [x] 提供自定义函数注册功能，注册后可以在表达式中使用\n- [x] 精确的数据计算\n- [x] 友好的错误消息 e.g.    \n```bash\ninput /\u003e 123+89-0.0.9\nERROR: strconv.ParseFloat: parsing \"0.0.9\": invalid syntax\nwant '(' or '0-9' but get '0.0.9'\n------------\n123+89-0.0.9\n       ^\n------------\n```\n\n","funding_links":[],"categories":["开源类库","Open source library"],"sub_categories":["解释器","Interpreter"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdengsgo%2Fmath-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdengsgo%2Fmath-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdengsgo%2Fmath-engine/lists"}