DEV Community

Md Marzukul Islam
Md Marzukul Islam

Posted on

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)
Enter fullscreen mode Exit fullscreen mode

So this simple code:

    System.out.println(0.1 + 0.2);
Enter fullscreen mode Exit fullscreen mode

prints:

    0.30000000000000004
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

For example:

    BigDecimal x = new BigDecimal("123.45");
Enter fullscreen mode Exit fullscreen mode

is stored as:

    intVal = 12345
    scale  = 2
    value  = 12345 × 10^-2 = 123.45
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)