Caveats
Caveats
A few boundaries worth scanning before you start — knowing these upfront can save a lot of debugging time.
1. Computation errors throw; only fmt has a fallback
calc, standalone arithmetic functions, aggregation, and chaining all throw on error (invalid expression, invalid argument, etc.) — you need to handle these with try/catch. Only the display-oriented fmt catches errors and returns a fallback value (default '-').
calc('1 / x') // ❌ throws: undefined variable
fmt('1 / x') // "-" ✅ fallback, page doesn't crash
calc for computation (errors should be visible), use fmt for display (stable, no crashes).2. calc has no variables — use template interpolation
calc is pure arithmetic evaluation — there is no variable support. Interpolate values directly into the expression string:
const price = 9.9
const qty = 3
calc(`${price} * ${qty}`) // ✅ "29.7"
// calc('price * qty', { price, qty }) ← old syntax, no longer supported
3. number-returning variants lose precision above 2^53
add / sub / mul / div return number. Results exceeding Number.MAX_SAFE_INTEGER (2^53) will lose precision. For monetary values or large integers, use the string variants addStr / subStr / mulStr / divStr, or use calc / fmt:
add('9007199254740993', '1') // 9007199254740994 ← number, may not be exact
addStr('9007199254740993', '1') // "9007199254740994" ✅ string, no loss
4. Input precision: values may already be corrupted before they arrive
For precision-sensitive values (monetary amounts, large integers), pass them as strings. A number literal can be corrupted by JS floating-point before it ever reaches the function — the library cannot recover from that:
addStr(0.1 + 0.2, 0) // "0.30000000000000004" ← argument already corrupted
addStr('0.1', '0.2') // "0.3" ✅
The same applies to template interpolation: calc(`${0.1} + ${0.2}`) is fine (interpolating the literals 0.1 and 0.2), but calc(`${0.1 + 0.2}`) first evaluates with floating-point and the result is already wrong.
5. Configuration: setConfig is a singleton with ordering requirements
setConfig modifies a global singleton and must be called before any calc / fmt invocations (typically in main.ts). If you only need different precision for a single division or average without affecting global state, pass { _precision } at the call site — no ordering concerns.
6. Division defaults to 50 decimal places
Repeating decimals (e.g. 1 / 3) are computed to 50 places by default. To adjust, use _precision (computation precision) or fmt's decimals (display places):
divStr('1', '3') // "0.333…" to 50 places
divStr('1', '3', { _precision: 10 }) // "0.3333333333"
fmt('1 / 3', { decimals: 4 }) // "0.3333"