Arbitrary-Precision Whole Numbers

Quick Overview

java.math.BigInteger is an immutable, arbitrary-precision integer class. While standard primitive types (int, long) have strict maximum limits, BigInteger can handle numbers of virtually limitless size, constrained only by your system’s available memory.


Why Do We Need BigInteger?

Standard Java integer types have fixed bit-widths and strict boundaries:

  • int (32 bits): Max value is ().
  • long (64 bits): Max value is ().

If you try to perform math that exceeds Long.MAX_VALUE, Java doesn’t throw an error by default—it silently overflows, wrapping around into negative numbers and producing corrupt data.

long maxLong = Long.MAX_VALUE;
System.out.println(maxLong);         // 9223372036854775807
System.out.println(maxLong + 1);     // -9223372036854775808 (Overflow !)

BigInteger eliminates this ceiling entirely.

How it Relates to BigDecimal

Remember how BigDecimal is built under the hood? It uses a BigInteger for its unscaled value!

  • BigInteger handles whole numbers (integers).
  • BigDecimal wraps a BigInteger and adds a scale factor to handle decimal points.

Basic Code Example

Just like BigDecimal, because BigInteger objects are immutable, you must use methods (.add(), .multiply(), etc.) instead of standard arithmetic operators (+, *).

import java.math.BigInteger;
public class BigIntegerExample {
    public static void main(String[] args) {
        // Creating BigIntegers from Strings to avoid long limits
        BigInteger num1 = new BigInteger("9223372036854775807999");
        BigInteger num2 = new BigInteger("1000000000000000000");
        // Use method calls for arithmetic, not operators!
        BigInteger sum = num1.add(num2);
        BigInteger product = num1.multiply(num2);
        System.out.println("Sum: " + sum);
        System.out.println("Product: " + product);
        // Built-in constants
        BigInteger zero = BigInteger.ZERO;
        BigInteger one = BigInteger.ONE;
    }
}

When Should You Use BigInteger?

  • Cryptography:
    • RSA encryption, Diffie-Hellman key exchanges, and hashing algorithms routinely require multiplying prime numbers that are hundreds or thousands of digits long.
  • Scientific & Mathematical Calculations:
    • Calculating massive factorials, combinatorial permutations, or astronomical distances where standard long variables overflow instantly.
  • Unique System IDs:
    • Handling massive 128-bit or 256-bit database identifiers/hashes as numeric values.

Performance Trade-off

Because BigInteger values are objects stored on the heap (rather than raw CPU registers), and because operations require dynamic memory allocation and custom algorithms for multi-word arithmetic, they are significantly slower than primitive long or int operations. Use them only when you genuinely need precision beyond 64 bits.