Dev.to WebDev 🛠 Dev 👁 0 📖 1 min read

Why 0.1 + 0.2 breaks your calculator (and how to handle money in JavaScript)

Open your browser console and type: 0.1 + 0.2; // 0.30000000000000004 That's not a JavaScript bug. It's how binary floating point works, and it matters when you're building anything that handles money.

Open your browser console and type:

0.1 + 0.2; // 0.30000000000000004

That's not a JavaScript bug. It's how binary floating point works, and it matters when you're building anything that handles money.

Why it happens

JavaScript numbers are 64-bit binary floats. Just as 1/3 can't be written exactly in decimal, 0.1 can't be written exactly in binary. Tiny errors get stored, and they surface after arithmetic.

Rounding is where it really bites:

(1.005).toFixed(2);          // "1.00"  (you probably expected "1.01")
Math.round(1.005 * 100) / 100; // 1     (same problem)

Fix 1: Use integers for money

Store amounts in the smallest unit, such as paise or cents, as whole numbers.

const priceInPaise = 19999;   // ₹199.99
const total = priceInPaise * 3; // 59997, exact

Convert only when displaying. Integer arithmetic below 2^53 is exact.

Fix 2: Use a decimal library when you need decimals

For things like tax or interest with many digits, libraries like decimal.js or big.js do arithmetic in base 10:

import Decimal from "decimal.js";

new Decimal("0.1").plus("0.2").toString(); // "0.3"

Pass numbers in as strings, otherwise you've already introduced the error.

Fix 3: Round once, at the end

For estimates such as compound interest or SIP projections, floats are usually fine. The rule is: don't round intermediate steps, and round only when you show the result.

const future = 5000 * Math.pow(1 + 0.12 / 12, 12 * 10);
console.log(future.toFixed(2));

Format for humans, not by hand

Don't write your own comma logic. Intl.NumberFormat handles grouping and currency, including the Indian lakh style:

new Intl.NumberFormat("en-IN").format(1234567);
// "12,34,567"

new Intl.NumberFormat("en-IN", { style: "currency", currency: "INR" })
  .format(1234567.5);
// "₹12,34,567.50"

Quick checklist

  • Never compare floats with === after arithmetic
  • Store money as integers or decimal strings
  • Round only for display
  • Use Intl.NumberFormat for formatting
  • Test with awkward values like 1.005, 0.1 + 0.2, and very large amounts

If you want reference numbers to test against, calculators like the compound interest and SIP tools on Erapse (my site) are useful for comparing results.

Have you hit a floating-point bug in production? I'd like to hear about it.

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.