Developer's Guide to Math Evaluator: Best Practices and Examples
August 18, 2026 · The Devs Tools Team
Evaluating a user-typed math expression like (3 + 4) * 2 / (1 - 5) sounds trivial until you actually try to do it safely. The naive approach — piping a string straight into JavaScript's eval() or the Function constructor — technically works, but it also happily executes arbitrary code if the input contains anything beyond arithmetic. A string like alert(document.cookie) is just as "evaluable" as a math expression to those APIs, which is why eval-based calculators are a recurring source of security findings. A proper expression evaluator instead tokenizes the input into numbers and operators, respects operator precedence and parentheses (typically via a recursive-descent parser or the shunting-yard algorithm), and rejects anything that isn't a legitimate arithmetic token. This matters just as much for spreadsheet-style formula fields, config file interpolation, and calculator widgets embedded in internal tools as it does for public-facing apps — anywhere user input reaches a "compute this" code path deserves the same scrutiny you'd give a SQL query.
[!TIP] Need to evaluate an expression right now? Try our free, local Math Evaluator to solve arithmetic expressions with correct operator precedence completely offline.
Why Operator Precedence Trips People Up
Standard math notation follows PEMDAS/BODMAS rules: parentheses first, then exponents, then multiplication and division (left to right), then addition and subtraction (left to right). A parser that just scans left-to-right without precedence awareness will get 2 + 3 * 4 wrong, returning 20 instead of 14. Correct evaluators build (or implicitly walk) an expression tree so that higher-precedence operators bind tighter:
2 + 3 * 4
+
/ \
2 *
/ \
3 4
=> 14
Common Pitfalls in Hand-Rolled Evaluators
- Unbalanced parentheses: a naive parser can silently drop a trailing
)instead of raising a syntax error, producing a plausible-looking but wrong result. - Division by zero:
5 / 0should surface asInfinityor an explicit error, not crash the whole evaluation. - Implicit multiplication: expressions like
2(3+4)are common in math notation but not valid JavaScript syntax — a robust evaluator needs to normalize this before parsing, or reject it clearly rather than throwing an opaque error. - Locale-specific decimal separators:
3,5means 3.5 in some locales and could be misread as two arguments in others.
A Practical Workflow
If you're validating a formula field in your own app, a fast sanity check is to run the expression through a browser-based evaluator first and compare it against your app's computed output:
Input: (10 - 4) * 3 + 8 / 2
Expect: 22
If your app's result diverges, the bug is almost always in operator precedence or in how you're tokenizing negative numbers versus subtraction.
Conclusion
Arithmetic evaluation looks like a solved problem, but the gap between "works for the demo" and "safe and correct for arbitrary input" is exactly where precedence bugs and injection vulnerabilities hide. Whether you're building a calculator feature or debugging a formula engine, testing expressions against a dedicated, sandboxed evaluator is a quick way to separate parser bugs from logic bugs.
