Caveats

A few edge cases worth knowing before you start — error handling, precision pitfalls, and configuration scope.

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
Rule of thumb: use 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"