🔢 Floating Point Imprecision

Understanding why 0.1 + 0.2 ≠ 0.3 in programming languages

!The Classic Problem

One of the most surprising behaviors for new programmers is discovering that simple decimal arithmetic doesn't work as expected in most programming languages.

let point3a = 0.1 + 0.2; let point3b = 0.3; console.log(point3a); // 0.30000000000000004 console.log(point3b); // 0.3 console.log(point3a === point3b); // false
Result: 0.1 + 0.2 = 0.30000000000000004
Expected: 0.3
Are they equal? false

🔍Binary Representation

The root cause lies in how computers store decimal numbers using the IEEE-754 standard. Let's examine the actual binary representations:

0.30000000000000004 (0.1 + 0.2)

00111111110100110011001100110011
00110011001100110011001100110100

0.3 (exact)

00111111110100110011001100110011
00110011001100110011001100110011
Key Insight: Only the last 2 bits differ (00 vs 11), but that's enough to make these numbers unequal in computer memory!

🧮Interactive Demo

Try your own calculations and see the floating point imprecision in action:

+

⚠️This is NOT a JavaScript Bug!

Important: This behavior is not unique to JavaScript. It occurs in virtually all programming languages that use IEEE-754 floating point arithmetic, including:

  • Python
  • Java
  • C/C++
  • C#
  • Ruby
  • And many others...

The temptation to make fun of JavaScript for this is strong, but it's completely unfounded!

💡Solutions & Workarounds

Here are practical ways to handle floating point comparisons and monetary calculations:

Method 1: Using Number.EPSILON

function isEqual(a, b) { return Math.abs(a - b) < Number.EPSILON; } console.log(isEqual(0.1 + 0.2, 0.3)); // true

Method 2: Rounding to fixed precision

let result = Math.round((0.1 + 0.2) * 100) / 100; console.log(result === 0.3); // true

Method 3: Using a tolerance value

function almostEqual(a, b, tolerance = 1e-10) { return Math.abs(a - b) < tolerance; } console.log(almostEqual(0.1 + 0.2, 0.3)); // true

Method 4: The Stripe Approach - Store as Integers

// Store money as smallest currency unit (cents) const priceInCents = 1050; // $10.50 const taxInCents = 105; // $1.05 const totalInCents = priceInCents + taxInCents; // 1155 // Convert back to dollars for display const totalInDollars = totalInCents / 100; // $11.55 // For API calls to Stripe: stripe.paymentIntents.create({ amount: totalInCents, // 1155 cents = $11.55 currency: 'usd' });

🏦 How Stripe Solves This Problem

Stripe's Solution: Store all monetary values as integers in the smallest currency unit. This completely eliminates floating point precision issues for financial calculations.

  • USD/EUR: Store as cents (e.g., $10.50 = 1050 cents)
  • JPY: Store as yen (e.g., ¥100 = 100, since yen has no decimal places)
  • All calculations: Performed on integers, avoiding floating point entirely
  • Display: Convert back to decimal format only when showing to users

Benefits: Perfect precision, no rounding errors, works with all currencies, and follows banking industry standards.