表达式计算器
生活安全求值算术表达式,支持 + − × ÷ % ^ 与括号。不使用 eval,不执行任意代码。
本页内容
这个计算器是什么?#
它是一个纯算术计算器——你把一个数学表达式当文字打进去,比如 (12 * 1.08) + 7 或 2^10 % 256,它给你一个数。没有一排要逐个去戳的函数按钮,你直接把整个表达式写好,按一次键就行。
关键是它怎么实现的。网上很多速算器其实是偷懒,把你的字符串交给 JavaScript 的 eval() 去跑——而 eval() 能执行任意代码,做个玩具还行,别人粘段巧妙的东西进来就难看了。本工具不是这样:它跑的是一个手写的递归下降解析器,只接受数字、括号和运算符 + - * / % ^,语法之外的任何东西当场就拒掉。结果就是一个真的没法执行代码的计算器,这也正是为什么它能放心地往里粘贴。
怎么使用#
- 在 输入 框里写表达式。空格会被忽略,
1+2和1 + 2完全等价。 - 运算符:四则运算用
+-*/,%是取模(求余数),^是乘方。括号()用来分组。一元负号可用,所以-5 + 3等于-2。 - 小数和科学计数法都支持:
0.5、1e3(就是 1000)、2.5e-2。 - 点 计算(或回车)。结果 行显示数值;若有问题,会就地提示具体原因——
除以零、未预期字符、括号不匹配等等——方便你直接修,而不是对着一个NaN干瞪眼。 - 二进制浮点的尾差会自动抹掉,所以
0.1 + 0.2显示0.3,而不是0.30000000000000004。
主要特性#
- 不用
eval、不用new Function、不接受标识符。 只接受数字和七个运算符字符——一个完全有界的语法,不是任意代码执行。 - 运算符优先级正确(PEMDAS):括号 →
^→* / %→+ -。 - 乘方右结合。
2^3^2按数学家的写法来算(见实例演示)。 - 科学计数法(
6.022e23)和取模(17 % 5),应付真正的草稿计算够用。 - 友好且明确的错误,会点出失败类型(除以零、表达式被截断、数字非法)和出错位置,而不是给个无声的
NaN。
实例演示#
下面三个表达式,各展示一种行为。一次粘一个。
运算符优先级与分组。
(1 + 2) * 3 ^ 2
结果:27。括号先把 1 + 2 = 3 算出来;接着 3 ^ 2 在乘法之前算(乘方比 * 结合得更紧),得到 9;最后 3 * 9 = 27。去掉括号的话,1 + 2 * 3 ^ 2 会是 1 + 18 = 19。
乘方右结合。
2 ^ 3 ^ 2
结果:512,不是 64。乘方向右结合,所以这是 2 ^ (3 ^ 2) = 2 ^ 9 = 512。如果你要的是 (2 ^ 3) ^ 2 = 64,那就把括号写出来。
抹掉二进制尾差。
0.1 + 0.2
结果:0.3。原始的二进制浮点求和是 0.30000000000000004;格式化把它四舍五回到合理有效位数,让结果读起来符合人的预期。
常见问题#
为什么不能用 sin、log、sqrt、pi?#
因为这些都是标识符,而标识符被刻意排除在语法之外。任何名字都会被当作 未预期字符 拒掉——正是这条线,让计算器永远跑不了代码。需要 sqrt(16),就改写成 16 ^ 0.5;要用 log、sin,请用科学计算器。
2^3^2 得到 512 还是 64?#
512。^ 是右结合的,符合数学里和大多数语言里乘方运算符的约定。2^3^2 解析为 2^(3^2)。想要 64,就写成 (2^3)^2。
这里的 % 是什么意思?#
是取模——整数除法之后的余数,不是”百分之”。17 % 5 等于 2,因为 17 除以 5 余 2。判断奇偶(n % 2)、把数值折回一个范围、钟表式的运算都常用到它。它的优先级和 *、/ 相同。
我输入的表达式会发到服务器吗?#
不会。解析和求值完全在你浏览器里用手写解析器完成——没有后端,输入从不离开本页。