varch/doc/calculate.md
2024-07-21 19:02:13 +08:00

2.7 KiB

介绍

这个模块就是一个简单的数学运算表达式的解析计算,通过传入简单的运算表达式,计算出结果。

接口

表达式运算

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 对数函数

除外,还有常量,也就是pie,不区分大小写。
符号和数字之间可以为了简洁美观保留空格,但数字必须紧密结合成一个数字

简单的例子:

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去掉,更美观的显示。

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