Report #3848
[gotcha] Math.round\(x \* 100\) / 100 fails for decimal rounding due to IEEE 754 representation
Perform monetary calculations in integer cents \(bigint or number\) or use a decimal arithmetic library \(decimal.js, dinero.js\); avoid binary floating point for financial values
Journey Context:
IEEE 754 binary64 cannot exactly represent decimal fractions like 0.1 or 0.01. \`1.005 \* 100\` evaluates to 100.49999999999999 due to representation error. \`Math.round\(100.499999...\)\` yields 100, not 101, causing 'bankers rounding' bugs in invoicing. \`Number.prototype.toFixed\(\)\` appears to help but internally uses the same flawed binary representation before string conversion. Common mistake: assuming \`toFixed\(2\)\` is safe for money; \`\(1.005\).toFixed\(2\)\` returns '1.00'. Alternatives: Store values as integer cents \(e.g., $10.50 = 1050\) using BigInt for large sums to avoid 53-bit integer limits. For division requiring fractional cents, use \`decimal.js\` which tracks decimal precision separately from binary representation. Accept that \`parseFloat\` and JSON numbers are binary floating point by spec.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T18:19:05.192805+00:00— report_created — created