BigInteger

Su Suriya Ravichandran Updated 14 Nov 2026
5 min read ·Lesson 108 of 133

java.math.BigInteger represents integers of arbitrary size. Where long stops at about 9.2 × 10¹⁸, a BigInteger can hold a number with thousands or millions of digits, limited only by memory. It never overflows: every operation produces the exact mathematical result. BigInteger is used in cryptography, combinatorics, number theory, very large identifiers and counters, and any calculation whose intermediate values exceed 64 bits.

Why long Is Not Always Enough

long f20 = 2_432_902_008_176_640_000L;     // 20! fits in a long
long f21 = f20 * 21;                        // overflow: -4249290049419214848

Multiplying past Long.MAX_VALUE silently wraps around to a negative number. Math.multiplyExact would at least throw an exception, but it cannot produce the correct value. BigInteger can:

BigInteger f21 = BigInteger.valueOf(2_432_902_008_176_640_000L).multiply(BigInteger.valueOf(21));
System.out.println(f21);    // 51090942171709440000

Creating BigIntegers

BigInteger a = BigInteger.valueOf(42);                          // from a long
BigInteger b = new BigInteger("123456789012345678901234567890"); // from decimal text
BigInteger c = new BigInteger("ff", 16);                        // from text in base 16 → 255
BigInteger d = BigInteger.ONE;                                   // constants: ZERO, ONE, TWO, TEN
  • Use valueOf for values that fit in a long; it may return cached instances.
  • Use the String constructor for larger values. Invalid text throws NumberFormatException.

Operations Are Methods, and Results Are New Objects

BigInteger is an object, so the arithmetic operators do not work on it. Each operation is a method that returns a new BigInteger; the original is immutable and never changes:

BigInteger x = BigInteger.ONE;
x.add(BigInteger.TEN);          // result discarded: x is still 1
x = x.add(BigInteger.TEN);      // correct: x is now 11

Forgetting to use the return value is the most common BigInteger mistake, exactly as with String.

Arithmetic

OperationMethodExample (a = 17, b = 5)
Additiona.add(b)22
Subtractiona.subtract(b)12
Multiplicationa.multiply(b)85
Divisiona.divide(b)3 (truncated toward zero)
Remaindera.remainder(b)2 (sign follows a)
Modulusa.mod(b)2 (always non-negative; b must be positive)
Quotient and remaindera.divideAndRemainder(b)[3, 2]
Powera.pow(3)4913
Negation, absolute valuea.negate(), a.abs()−17, 17
Integer square roota.sqrt()4 (Java 9+)

Division by zero throws ArithmeticException.

Operations chain naturally:

BigInteger result = a.multiply(a).add(b).mod(BigInteger.valueOf(1_000_000_007));

Number theory

MethodPurpose
gcd(b)Greatest common divisor
modPow(exp, m)(this^exp) mod m, computed efficiently even for huge exponents
modInverse(m)Multiplicative inverse modulo m
isProbablePrime(certainty)Primality test (probability of error at most 2^−certainty)
nextProbablePrime()Next probable prime greater than this value
BigInteger.valueOf(48).gcd(BigInteger.valueOf(180));     // 12
BigInteger.valueOf(7).modPow(BigInteger.valueOf(128), BigInteger.valueOf(13));   // 3
BigInteger.valueOf(97).isProbablePrime(20);              // true
BigInteger.valueOf(100).nextProbablePrime();             // 101

modPow and modInverse are the core operations of public-key cryptography such as RSA. (Real cryptographic code should use the java.security and javax.crypto APIs rather than hand-built algorithms.)

Bit operations

BigInteger supports and, or, xor, not, shiftLeft, shiftRight, testBit, setBit, clearBit, bitLength, and bitCount, treating the value as an infinitely sign-extended two's-complement number. bitLength() is a convenient way to check how many bits a value needs.

Comparing

BigInteger has no < or >; use compareTo, and use equals for equality:

BigInteger a = new BigInteger("10");
a.compareTo(BigInteger.ONE) > 0;      // true: a > 1
a.equals(BigInteger.TEN);             // true
a == BigInteger.TEN;                  // false: different objects
a.signum();                           // 1 (also -1 or 0)
a.max(BigInteger.TWO);                // 10

BigInteger implements Comparable, so it can be sorted and used as a TreeMap key, and it implements equals/hashCode correctly for HashMap.

Converting Back to Primitives and Text

BigInteger big = new BigInteger("51090942171709440000");

big.toString();             // "51090942171709440000"
big.toString(16);           // hexadecimal text
big.longValue();            // -4249290049419214848: silently keeps only the low 64 bits
big.longValueExact();       // ArithmeticException: BigInteger out of long range
big.doubleValue();          // 5.109094217170944E19 (approximate)

intValue() and longValue() truncate silently, just like narrowing casts. Use intValueExact() and longValueExact() when a value is expected to fit and a wrong result would be worse than an exception.

Performance

BigInteger arithmetic runs in software, on arrays of 32-bit words, and allocates a new object for every result. It is much slower than long arithmetic: fine for exact computations on occasional large numbers, wasteful for ordinary counters and loops. Use long when values fit (and Math.*Exact methods to detect overflow), and switch to BigInteger only where the range is genuinely needed.

Practical Example: Factorials and Combinations

Counting arrangements, lottery odds, and probability calculations quickly produce numbers far beyond long.

import java.math.BigInteger;

public class BigI {
    static BigInteger factorial(int n) {
        BigInteger result = BigInteger.ONE;
        for (int i = 2; i <= n; i++) result = result.multiply(BigInteger.valueOf(i));
        return result;
    }

    static BigInteger choose(int n, int k) {
        BigInteger r = BigInteger.ONE;
        for (int i = 1; i <= k; i++) {
            r = r.multiply(BigInteger.valueOf(n - k + i)).divide(BigInteger.valueOf(i));
        }
        return r;
    }

    public static void main(String[] args) {
        System.out.println("20! = " + factorial(20) + " (fits in long: " + (factorial(20).bitLength() < 64) + ")");
        System.out.println("21! = " + factorial(21) + " (fits in long: " + (factorial(21).bitLength() < 64) + ")");
        System.out.println("50! has " + factorial(50).toString().length() + " digits");
        System.out.println("C(100, 50) = " + choose(100, 50));
        try {
            System.out.println(factorial(21).longValueExact());
        } catch (ArithmeticException e) {
            System.out.println(e.getMessage());
        }
    }
}

Output:

20! = 2432902008176640000 (fits in long: true)
21! = 51090942171709440000 (fits in long: false)
50! has 65 digits
C(100, 50) = 100891344545564193334812497256
BigInteger out of long range

Each step reassigns result = result.multiply(...), because multiply returns a new object. bitLength() < 64 checks whether a value would fit in a signed long: 20! needs 62 bits and fits, while 21! needs 66. choose computes combinations without calculating the full factorials. Multiplying before dividing at each step keeps every intermediate value a whole number, since the running product after step i is itself a binomial coefficient, so the division is always exact. C(100, 50), the number of ways to choose 50 items from 100, has 30 digits; no primitive type could hold it. Finally, longValueExact refuses to convert 21! to a long instead of silently returning a wrong negative number.

0 Comments

Reviewed before they appear

No comments yet.

Java
Java Introduction Java Features Java Syntax Java Comments Java Statements Java Output Java Variables Java Data Types Java Type Casting Java Operators Java Strings Java Numbers Java Math Java Booleans Java User Input Java Conditions Java If Else Java Switch Java While Loop Java For Loop Java Break Java Continue Java Arrays Java Methods Java Parameters Java Return Values Java Scope Java Recursion Install Java Install JDK Java IDEs Java JDK Java JRE Java JVM Java Compiler Java File Compile Java Run Java JShell Basics Java Packages Java OOP Java Classes Java Objects Class Methods Constructors Constructor Overload this Keyword static Keyword final Keyword Encapsulation Inheritance Polymorphism Abstraction Access Modifiers super Keyword Method Overload Method Override Instanceof Operator Nested Classes Inner Classes Anonymous Classes Enums Records Array Basics Array Length Loop Arrays Multidimensional Arrays Array Copy Array Sorting Array Search ArrayList LinkedList HashSet TreeSet HashMap TreeMap Queue Interface Deque Interface Stack Class Iterator List Interface Set Interface Map Interface Collections Class Comparable Comparator Generics Basics Generic Classes Generic Methods Wildcards String Basics String Length String Methods String Concatenation String Compare String Search String Replace String Split String Format StringBuilder StringBuffer Text Blocks Regular Expressions Number Types Integer Class Float Class Double Class BigInteger BigDecimal Math Class Random Numbers Number Format Date Basics LocalDate LocalTime LocalDateTime ZonedDateTime Date Formatting Date Parsing Period Class Duration Class Java Instant Class Java Exception Basics Java try...catch Java Multiple Catch Blocks Java finally Block Java throw Keyword Java throws Keyword Java Checked Exceptions Java Unchecked Exceptions Java Custom Exceptions Java try-with-resources Java Exception Chaining
Ask about this post
AI Ask about this post

Ask questions about BigInteger and get answers drawn from it.

Signed-in readers only.