40.1 BigDecimal And BigInteger

Perform arbitrary-precision arithmetic for financial calculations and large integer operations.

BigDecimal Basics

import java.math.*;

BigDecimal price = new BigDecimal("19.99");
BigDecimal tax = new BigDecimal("0.08");
BigDecimal total = price.add(price.multiply(tax));

Always use string constructor to avoid floating-point errors:

// BAD: new BigDecimal(0.1) -> 0.1000000000000000055511151231257827021181583404541015625
// GOOD:
BigDecimal val = new BigDecimal("0.1");

Rounding Modes

BigDecimal result = price.divide(new BigDecimal("3"), 2, RoundingMode.HALF_UP);

Common modes:

  • HALF_UP: Round to nearest; ties away from zero.
  • HALF_EVEN: Banker's rounding (ties to even).
  • DOWN: Truncate toward zero.

Scale and Precision

BigDecimal val = new BigDecimal("123.4500");
int scale = val.scale(); // 4
int precision = val.precision(); // 7

BigDecimal scaled = val.setScale(2, RoundingMode.HALF_UP); // 123.45

Currency Calculations

MathContext mc = new MathContext(2, RoundingMode.HALF_UP);
BigDecimal amount = new BigDecimal("100.00");
BigDecimal rate = new BigDecimal("0.035");
BigDecimal interest = amount.multiply(rate, mc);

BigInteger

BigInteger a = new BigInteger("123456789012345678901234567890");
BigInteger b = new BigInteger("987654321098765432109876543210");
BigInteger sum = a.add(b);
BigInteger product = a.multiply(b);

Performance

  • Immutable; each operation creates a new instance.
  • Slower than primitive types; use primitives when range suffices.
  • Reuse MathContext for repeated operations.

Guidance

  • Use BigDecimal for financial calculations; never double/float.
  • Always specify rounding mode for division.
  • Use string constructors to preserve exact decimal values.
  • Set appropriate scale for currency (typically 2 for USD).
  • Use compareTo for equality checks, not equals (scale-sensitive).