Go 实现的数学表达式解析计算引擎 math-engine

Apache
Google Go
跨平台
2019-07-08
奋斗de熊猫
math-engine 正在参加 2019 年度最受欢迎开源中国软件评选,请投票支持!
math-engine 在 2019 年度最受欢迎开源中国软件评选 中已获得 {{ projectVoteCount }} 票,请投票支持!
投票赢奖品
已投票

使用 Go 实现的数学表达式解析计算引擎库,无任何依赖,相对比较完整的完成了数学表达式解析执行,包括词法分析、语法分析、构建AST、运行。

能够处理的表达式样例:

  • 1+127-21+(3-4)*6/2.5
  • (88+(1+8)*6)/2+99
  • 123_345_456 * 1.5 - 2 ^ 4
  • -4 * 6 + 2e2 - 1.6e-3
  • sin(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

asciicast

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
^ 整数次方,integer power 2^3 = 8, 3^2 = 9
e 科学计数法,E-notation 1.2e3 = 1200,1.2e-2 = 0.012
() 括号,brackets (2+3)*4 = 20
_ 数字分隔符,number separator 123_456_789 = 123456789
pi π pi = 3.141592653589793
sin(x) 正弦函数,sine sin(pi/2) = 1
cos(x) 余弦函数,cosine cos(0) = 1
tan(x) 正切函数,tangent tan(pi/4) = 1
cot(x) 余切函数,cotangent cot(pi/4) = 1
sec(x) 正割函数,secant sec(0) = 1
csc(x) 余割函数,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 直接调用解析执行函数 :

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 依次调用函数,手动执行 :

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)
}

编译运行,应该可以看到如下输出:

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

三角函数的参数类型默认为弧度RadianMode,e.g. sin(pi/2) = 1.

你可以通过设置 TrigonometricMode 调整参数类型,可选 弧度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

也可以直接下载已编译好的二进制文件,直接运行:

Github Releases

实现细节

请阅读我的博客文章:用 Go 实现一个完整的数学表达式计算引擎

TODO

已实现

  •  加 +
  •  减 -
  •  乘 *
  •  除 /
  •  取余 %
  •  整数次方 ^
  •  科学计数法 e.g. 1.2e7、 1.2e-7
  •  括号 ()
  •  混合运算 e.g. 1+2*6/4+(456-8*9.2)-(2+4^5)*2e3+1.2e-2
  •  友好的长数字 e.g. 123_456_789
  •  三角函数 e.g. sin, cos, tan, cot, sec, csc
  •  常量 pi
  •  辅助函数 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
       ^
------------

待实现

  •  精确浮点计算
  •  更多辅助函数
的码云指数为
超过 的项目
加载中

评论(0)

暂无评论

math-engine v2.0,数学表达式解析计算引擎

更新日志: 增加 常量 pi 增加 三角函数支持 sin(), cos(), tan(), cot(), sec(), csc() 增加 三角函数参数调整,可选 弧度RadianMode、角度AngleMode 增加 辅助函数 abs(), ceil(), floor()...

07/15 09:38

没有更多内容

加载失败,请刷新页面

没有更多内容

暂无问答

游戏开发方向指引

一直想学OpenGL,要精通OpenGL还要有专研的精神,图形学、数学。同时想到以后的工作真的要接触3D游戏开发吗?现在游戏引擎都做的那么好,能快速开发商业游戏的需求,用着不是很好吗。想到这就...

2012/03/28 10:23
594
0
MAX函数和GROUP BY 语句一起使用的一个误区

使用MAX 函数和 GROUP 的时候会有不可预料的数据被SELECT 出来。 下面举个简单的例子: 想知道每个SCOREID 的 数学成绩最高的分数。 表信息: /*DDL Information For - test.lkscore*/ -----...

2014/04/05 23:58
130
0
自制简单搜索引擎

搜索引擎(Search Engine)是指根据一定的策略、运用计算机技术从互联网上搜集信息,在对信息进行组织和处理后,为用户提供检索服务。在日常生活中,可以看到 Google 等 Web 检索网站,还有邮...

2016/01/11 16:50
225
1
MYSQL_使用外键约束(constraint)或触发器(trigger)来进行级联更新、删除

我们通常有这样的需求:删除表Table 1中记录,需要同时删除其它表中与Table 1有关的若干记录。 举个例子: 现有2个实体- 麻将机 学生、课程,1种联系- 成绩 分别创建 学生表 students, 课程表c...

2015/06/08 10:07
1K
1
game engine architecture---1.6

开篇就是一个非常赞的图标,显示了一个粗略的游戏engine的结构,尽管只是粗略,但是已经占了整整一页,相当赞。 读这里突然就觉得花钱买这个书和花时间读这个书绝对值得的。 想自己写engine的...

2012/03/09 14:07
99
0
一些游戏编程的书[转]

Game Developer Magazine 1994 - 2000年,共7年的游戏开发者杂志电子版(含源码) Graphics Programming Black Book (by Michael Abrash),图形编程黑书,Id software的Michael Abrash编著 ...

2016/06/20 13:40
13
0
一些游戏编程的书[转]

Game Developer Magazine 1994 - 2000年,共7年的游戏开发者杂志电子版(含源码) Graphics Programming Black Book (by Michael Abrash),图形编程黑书,Id software的Michael Abrash编著 ...

2016/06/20 13:39
46
0
Aspose.Words for Java v19.9新功能:实现创建重复节结构化文档标签能力!

Aspose.Words for Java是功能丰富的Word处理API,允许开发人员在不使用Microsoft Word的情况下嵌入在自己的Java应用程序中生成,修改,转换,呈现和打印文档的功能。同时还提供访问和操作所有...

09/16 15:23
24
0
一些游戏编程的书[转]

Game Developer Magazine 1994 - 2000年,共7年的游戏开发者杂志电子版(含源码) Graphics Programming Black Book (by Michael Abrash),图形编程黑书,Id software的Michael Abrash编著 ...

2016/06/20 13:39
6
0

没有更多内容

加载失败,请刷新页面

返回顶部
顶部