BigDecimal & BigInteger — exact arithmetic
Why floating-point fails for money, and how BigDecimal solves it.
The floating-point problem
Binary floating-point (double, float) cannot represent most decimal fractions exactly. The classic demonstration:
System.out.println(0.1 + 0.2); // 0.30000000000000004
For financial calculations, exam scores, or anywhere exactness matters, use BigDecimal:
BigDecimal a = new BigDecimal("0.1"); // from String — EXACT
BigDecimal b = new BigDecimal("0.2"); // from String — EXACT
BigDecimal c = a.add(b); // 0.3 — exactly
Construction from a double re-introduces the imprecision you were trying to avoid:
new BigDecimal(0.1) // → 0.1000000000000000055511151231257827021181583404541015625
Always construct BigDecimal from a String.
Arithmetic operations — all return new BigDecimal instances:
c.subtract(b); // subtraction
c.multiply(new BigDecimal("2")); // multiplication
c.divide(new BigDecimal("3"), 2, RoundingMode.HALF_UP); // scale 2 decimal places
c.setScale(2, RoundingMode.HALF_UP); // round to 2 decimal places
Comparison: use compareTo, not equals. equals also compares scale: new BigDecimal("2.0").equals(new BigDecimal("2.00")) is false. compareTo returns 0 for equal value:
new BigDecimal("2.0").compareTo(new BigDecimal("2.00")) == 0 // true
BigInteger handles arbitrarily large integers without overflow:
BigInteger factorial100 = BigInteger.ONE;
for (int i = 1; i <= 100; i++) factorial100 = factorial100.multiply(BigInteger.valueOf(i));