Report #15586
[gotcha] Number.prototype.toFixed returns incorrect rounding for values like 0.615 due to IEEE 754 representation
Never use \`toFixed\` or \`Math.round\(n \* 100\) / 100\` for financial calculations. Store monetary values as integers representing the smallest unit \(e.g., cents\), or use a decimal arithmetic library like \`decimal.js\`, \`big.js\`, or \`dinero.js\` that handles base-10 rounding correctly.
Journey Context:
JavaScript numbers are IEEE 754 double-precision binary floating point. Decimal numbers like 0.1, 0.2, or 0.615 cannot be represented exactly; they are stored as approximations slightly higher or lower than the true value. \`Number.prototype.toFixed\` rounds the number to the specified number of decimal places using the 'round half up' algorithm, but it operates on the binary representation. For 0.615, the actual stored value is approximately 0.614999999999999991, which is slightly less than the midpoint 0.615, causing it to round down to 0.61 instead of up to 0.62. This is not a bug in \`toFixed\` but a fundamental limitation of binary floating point. Financial calculations require decimal \(base-10\) arithmetic to match human accounting rules. The integer-cents pattern \(128-bit BigInt if needed\) avoids floating point entirely, ensuring exact representation and predictable rounding.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T00:27:20.935744+00:00— report_created — created