2 min read

Why Using Float for Money Calculations Is Dangerous

Why Using Float for Money Calculations Is Dangerous

Every engineer has done it at least once. You need to handle money, so you reach for the obvious choice: a floating-point number. double price = 19.99; — looks right. It isn't.

The Problem in One Line

>>> 0.1 + 0.2
0.30000000000000004

That extra 0.00000000000000004 is not a Python bug. It's how IEEE 754 floating-point arithmetic works in every language. Floats represent numbers as binary fractions, and many decimal values (like 0.1) are repeating fractions in binary — just like 1/3 is 0.333... in decimal. They cannot be represented exactly.

When you're calculating a product price, this rounding error is invisible. When you're running a payment system processing millions of transactions, those invisible errors compound into real money.

Real-World Consequences

In 2020, a major fintech startup discovered their accounting was off by $32 million over three years. The root cause? A FLOAT column in MySQL used for transaction amounts. Every tax calculation, every fee split, every currency conversion — all built on a foundation that was slightly wrong.

Another example: in 2023, a European bank's mortgage calculator showed customers wrong monthly payments because the JavaScript frontend used Number (IEEE 754 double) for amortization formulas. The error was only a few cents per month — but multiplied across 200,000 mortgages over 30 years, that's real money.

The Right Way

In Your Database

Never use FLOAT or DOUBLE for money columns. Use DECIMAL or NUMERIC with explicit precision:

-- Wrong
amount FLOAT

-- Right
amount DECIMAL(19, 4)  -- 15 digits before decimal, 4 after

In Your Application Code

Java / Kotlin:

// Wrong
val price: Double = 19.99

// Right
val price = BigDecimal("19.99")

Python:

# Wrong
price = 19.99

# Right
from decimal import Decimal
price = Decimal("19.99")

JavaScript / TypeScript:

// Wrong
const price = 19.99;

// Right — store as integer cents
const priceCents = 1999;

// Or use a library
import Decimal from 'decimal.js';
const price = new Decimal('19.99');

The Integer Cents Pattern

The simplest approach that works everywhere: store money as the smallest unit (cents, satang, paise) in an integer.

$19.99 → store as 1999 cents
¥1000 → store as 1000 yen
BTC 0.001 → store as 100000 satoshis

No floating point. No rounding errors. Just integers.

When Float IS Acceptable

  • Scientific computing (measurement uncertainty already exists)
  • Graphics and gaming (a few pixels off doesn't matter)
  • Machine learning (probabilities are inherently approximate)
  • Analytics and dashboards (trends matter more than precision)

The Rule

If the number represents value that people care about — money, inventory, votes — use exact types. If it represents physical measurement — temperature, velocity, pixel position — float is fine.

Money is the first category. Always.