Why 0.1 + 0.2 β 0.3 in Programming
π― The Questionβ
"Why does executing
0.1 + 0.2 == 0.3evaluate tofalsein Python, JavaScript, Java, and C++ (resulting in0.30000000000000004)? Why is using floating-point types strictly forbidden in financial and banking software?"
β‘ 30-Second Elevator Pitchβ
Computers do not store numbers in decimal (Base 10); they store them in binary (Base 2) using the IEEE 754 Floating-Point Standard.
- In decimal, a fraction can only be represented cleanly with finite digits if its denominator has prime factors of only 2 and 5 (like or ). Factions like repeat infinitely.
- In binary, a fraction can only be finite if its denominator is a pure power of 2.
- Because the decimal number 0.1 is (which contains factor 5), in binary it becomes an infinitely repeating fraction:
Because standard 64-bit double-precision floats have only a 53-bit mantissa (significand), the infinite stream is truncated and rounded, yielding:
π§ Under-the-Hood: Binary Mantissa Truncationβ
π¬ How Fintech & Banking Architectures Handle Moneyβ
In banking and e-commerce platforms, storing money in float or double is an instant bug that causes balances to drift over time.
Production solutions enforce two patterns:
- Integer Minor Units (Cents / Paise): Store all amounts as integers representing the smallest currency unit:
- Instead of storing
$10.50asfloat 10.50, store1050cents as a 64-bit integer (BIGINT).
- Instead of storing
- Arbitrary-Precision Decimal Types:
- Java:
BigDecimal - Python:
decimal.Decimal - SQL:
DECIMAL(19, 4)/NUMERIC
- Java:
π Comparison Matrix: Floating-Point vs. Fixed-Point / Integerβ
| Dimension | float / double (IEEE 754) | BigDecimal / DECIMAL(18,2) | Integer Minor Units (Cents / Paise) |
|---|---|---|---|
| Precision | Inexact / Approximate | Exact decimal precision | Exact integer precision |
| CPU Execution | β‘ Blazing fast (Direct FPU hardware) | π’ Slower (Software-emulated math) | β‘ Blazing fast (Standard integer ALU) |
| Memory Footprint | 4 to 8 bytes | Heavy heap object allocations | 8 bytes (int64_t / BIGINT) |
| Rounding Errors | Inevitable on decimal fractions | Fully controlled rounding modes | Zero fractional rounding drift |
| Use Cases | 3D graphics, physics simulations, ML | Core accounting, tax engines | Stripe, PayPal, billing APIs |
π‘ What Interviewers Ask Next (Follow-Up Traps)β
-
"How should you safely compare two floating-point numbers in code?"
- Answer: Never use strict equality (
a == b). Compare using an epsilon tolerance window:# Safe floating-point equality check
def is_equal(a, b, epsilon=1e-9):
return abs(a - b) < epsilon
- Answer: Never use strict equality (
-
"What is Bankers' Rounding (Half-Even Rounding), and why do financial systems mandate it?"
- Answer: Standard elementary rounding (round half up) creates an upward statistical bias over millions of transactions. Bankers' Rounding rounds
.5to the nearest even number (e.g.2.5 -> 2and3.5 -> 4). This ensures that over massive datasets, rounding errors cancel each other out symmetrically.
- Answer: Standard elementary rounding (round half up) creates an upward statistical bias over millions of transactions. Bankers' Rounding rounds
Interview Answer: 0.1 + 0.2 != 0.3 because computers store numbers in binary floating-point (IEEE 754). The fraction is an infinitely repeating fraction in binary, just as is in decimal. Truncating to the 53-bit mantissa introduces tiny precision errors. Financial systems avoid floats by using integer minor units (cents) or arbitrary-precision BigDecimal.
πΊ Video Explanationβ
Never Study in Isolation. Join Binary Dose.
Connect with fellow engineers, clear conceptual doubts, and get 2 visual breakdowns & engineering mental models daily across our community channels.
Discord Community
Start at #welcome-and-rules, say hello in #general-chat, clear doubts, and collaborate with engineers worldwide.