## 介绍 这个模块就是一个简单的数学运算表达式的解析计算,通过传入简单的运算表达式,计算出结果。 ## 接口 ### 表达式运算 ```c double calculate(const char *expression); ``` 这个函数用法很简单,传入表达式,返回运算结果。默认返回的数据为双精度浮点型,表示的范围会比较广,也适合浮点运算。当计算出错时候,就会返回`NAN`。 所支持的运算符包括:加法`+`,减法`-`,乘法`*`,除法`/`,次方`^`,取模`%`。运算的优先级有 | 运算符 | 优先级 | |:------:|:-----:| | ^ | 0 | | * / % | 1 | | + - | 2 | 除了,基本的运算符运算之外,还支持内置函数的运算。函数名后面跟着`()`,括号内传入函数参数,多个参数就通过逗号`,`隔开。 | 函数 | 参数 | 描述 | |:-----:|:-----:|:------:| | abs | 1 | 绝对值 | | sqrt | 1 | 开平方 | | exp | 1 | 自然指数 | | ln | 1 | 自然对数 | | sin | 1 | 正弦 | | cos | 1 | 余弦 | | tan | 1 | 正切 | | cot | 1 | 余切 | | asin | 1 | 反正弦 | | acos | 1 | 反余弦 | | atan | 1 | 反正切 | | acot | 1 | 反余切 | | ceil | 1 | 向上取整 | | floor | 1 | 向下取整 | | min | 2 | 两者中较小者 | | max | 2 | 两者中较大者 | | pow | 2 | 次方函数,与`^`一致 | | log | 2 | 对数函数 | 除外,还有常量,也就是`pi`和`e`,不区分大小写。 符号和数字之间可以为了简洁美观保留空格,**但数字必须紧密结合成一个数字**。 简单的例子: ```c void test(void) { printf("mul %lf\r\n", calculate(" ( 99 * 3 ) ")); printf("min %lf\r\n", calculate(" min (12, 3)")); printf("sin %lf\r\n", calculate("sin ( 11 / 2 * pi ) + 100 ")); } ``` 运算结果: ``` mul 297.000000 min 3.000000 sin 99.000000 ``` 可以将这个计算模块作为命令导出,以命令形式来计算。这个命令函数,已经将小数点后面没用的`0`去掉,更美观的显示。 ```c int command_calculate(int argc, char *argv[]) { double r = NAN; if (argc < 2) return 0; r = calculate(argv[1]); if (fabs(floor(r) - r) <= DBL_EPSILON && fabs(r) < 1.0e60) printf("%.0lf\r\n", r); else if (fabs(r) < 1.0e-6 || fabs(r) > 1.0e9) printf("%e\r\n", r); else { char p[64]; int len = 0; len = sprintf(p, "%lf", r); while (len > 0 && p[len-1] == '0' && p[len-2] != '.') {p[--len] = 0;} printf("%s\r\n", p); } return 1; } void test(void) { command_export("cal", command_calculate); } ``` 输入命令: ``` cal "sin( 11 / 2 * pi ) + 2 ^ 3" ``` 运算结果: ``` 7 ```