If you’ve ever wondered why developers always say “never use double for money”, here’s the real reason, and why BigDecimal solves the problem perfectly.
1. The Root Cause: Binary VS Decimal Representation
A double in Java uses IEEE 754 binary floating point, meaning it represents numbers as sums of powers of 2, not 10.
That works fine for many numbers, but not for decimals like 0.1 or 0.2, because they can’t be represented exactly in binary.
They become repeating binary fractions:
0.1₁₀ = 0.0001100110011001100...₂ (infinite)
So this simple code:
System.out.println(0.1 + 0.2);
prints:
0.30000000000000004
That tiny error is a rounding artifact, and in finance or accounting, it’s unacceptable.
2. How BigDecimal Fixes It
BigDecimal doesn’t use floating-point math at all.
Internally, it stores two things:
BigInteger intVal; // exact integer value
int scale; // how many digits after the decimal point
For example:
BigDecimal x = new BigDecimal("123.45");
is stored as:
intVal = 12345
scale = 2
value = 12345 × 10^-2 = 123.45
Which is 100% exact, no rounding errors.
That’s because:
-
BigIntegerholds whole numbers precisely in binary. - The scale simply shifts the decimal point in base 10.
3. Why BigDecimal Is Perfect for Money
Money works in decimal, not binary.
BigDecimal uses decimal arithmetic, so values like 0.1, 19.99, or 123456.78 are stored and calculated exactly as written, no binary drift, no rounding surprises.
Yes, it’s slower than double, but it’s correct and correctness is what matters in financial systems.
Top comments (0)