A Tiny Decimal That Caused Big Trouble, Until I Learned About BigDecimal

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:

  • BigInteger holds 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.

Leave a Reply