Of course! Here is a comprehensive guide to using BigInteger in Java, covering what it is, why you need it, and how to use it with code examples.

What is BigInteger?
In Java, primitive data types like int and long have a fixed size. An int is 32 bits, and a long is 64 bits. This means they can only store numbers within a specific range:
int: -2,147,483,648 to 2,147,483,647long: -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
What happens if you need to work with a number larger than this? For example, calculating 1000! (1000 factorial) results in a number with thousands of digits. This is where java.math.BigInteger comes in.
BigInteger is a Java class that can represent integers of arbitrary precision. It can hold a number with as many digits as your computer's memory can handle.
Key Characteristics of BigInteger
- Immutable: Like
String,BigIntegerobjects are immutable. Any operation that modifies aBigInteger(like addition or multiplication) will return a newBigIntegerobject. The original object remains unchanged. - Object, not Primitive: It's a class, not a primitive type. You must create instances of it using the
newkeyword or static factory methods. - Not Primitives: You cannot use
BigIntegerwith arithmetic operators like , , , . You must use its methods (add(),subtract(), etc.).
How to Use BigInteger
First, you need to import the class:

import java.math.BigInteger;
Creating a BigInteger
You have several ways to create a BigInteger:
public class BigIntegerExample {
public static void main(String[] args) {
// From a String (most common way for large numbers)
BigInteger bigIntFromString = new BigInteger("123456789012345678901234567890");
// From a primitive long
BigInteger bigIntFromLong = BigInteger.valueOf(9876543210L);
// From an array of bytes (low-level)
byte[] bytes = {1, 2, 3, 4};
BigInteger bigIntFromBytes = new BigInteger(bytes);
// Predefined constants
BigInteger zero = BigInteger.ZERO;
BigInteger one = BigInteger.ONE;
BigInteger ten = BigInteger.TEN;
System.out.println("From String: " + bigIntFromString);
System.out.println("From long: " + bigIntFromLong);
System.out.println("From bytes: " + bigIntFromBytes);
System.out.println("Zero: " + zero);
}
}
Arithmetic Operations
This is the most important part. You cannot use , , etc. You must use the object's methods.
BigInteger num1 = new BigInteger("12345678901234567890");
BigInteger num2 = new BigInteger("98765432109876543210");
// Addition
BigInteger sum = num1.add(num2);
System.out.println("Sum: " + sum); // 111111111011111111100
// Subtraction
BigInteger difference = num2.subtract(num1);
System.out.println("Difference: " + difference); // 86419753208641975320
// Multiplication
BigInteger product = num1.multiply(num2);
System.out.println("Product: " + product); // A very large number...
// Division
BigInteger quotient = num2.divide(num1);
System.out.println("Quotient: " + quotient); // 8
// Modulo (Remainder)
BigInteger remainder = num2.remainder(num1);
System.out.println("Remainder: " + remainder); // 2
Comparison
You cannot use <, >, to compare BigInteger values. Use the compareTo method.
compareTo()returns:-1if the number is less than the argument.0if the numbers are equal.1if the number is greater than the argument.
BigInteger a = new BigInteger("500");
BigInteger b = new BigInteger("1000");
BigInteger c = new BigInteger("500");
int result1 = a.compareTo(b); // a < b
System.out.println("a < b? " + (result1 < 0)); // true
int result2 = a.compareTo(c); // a == c
System.out.println("a == c? " + (result2 == 0)); // true
int result3 = b.compareTo(a); // b > a
System.out.println("b > a? " + (result3 > 0)); // true
You can also use convenient methods like equals(), greaterThan(), and lessThan() (though the latter two are added via helper classes or Java 17+ BigInteger extensions).

Bitwise Operations
BigInteger supports all standard bitwise operations.
BigInteger x = new BigInteger("1010", 2); // Binary "1010" is 10 in decimal
BigInteger y = new BigInteger("1100", 2); // Binary "1100" is 12 in decimal
// AND
BigInteger andResult = x.and(y); // 1000 (binary) = 8 (decimal)
System.out.println("AND: " + andResult);
// OR
BigInteger orResult = x.or(y); // 1110 (binary) = 14 (decimal)
System.out.println("OR: " + orResult);
// XOR
BigInteger xorResult = x.xor(y); // 0110 (binary) = 6 (decimal)
System.out.println("XOR: " + xorResult);
// NOT (Note: BigInteger is signed, so this flips all bits including the sign)
BigInteger notResult = x.not();
System.out.println("NOT: " + notResult);
// Shifts
BigInteger shiftLeft = x.shiftLeft(2); // 101000 (binary) = 40 (decimal)
BigInteger shiftRight = x.shiftRight(1); // 101 (binary) = 5 (decimal)
System.out.println("Shift Left 2: " + shiftLeft);
System.out.println("Shift Right 1: " + shiftRight);
Utility Methods
BigInteger has many other useful methods.
// Power
BigInteger base = new BigInteger("2");
BigInteger exponent = new BigInteger("10");
BigInteger power = base.pow(10); // 2^10 = 1024
System.out.println("Power (2^10): " + power);
// Absolute Value
BigInteger negative = new BigInteger("-987654321");
BigInteger absolute = negative.abs();
System.out.println("Absolute Value: " + absolute);
// GCD (Greatest Common Divisor)
BigInteger numA = new BigInteger("54");
BigInteger numB = new BigInteger("24");
BigInteger gcd = numA.gcd(numB); // gcd(54, 24) = 6
System.out.println("GCD: " + gcd);
// Prime Number Test (Probabilistic)
BigInteger primeCandidate = new BigInteger("17");
BigInteger notPrime = new BigInteger("18");
System.out.println("Is 17 prime? " + primeCandidate.isProbablePrime(10)); // true
System.out.println("Is 18 prime? " + notPrime.isProbablePrime(10)); // false
// The argument '10' is the certainty. Higher values mean higher certainty.
Practical Example: Calculating Factorial
This is a classic use case for BigInteger. Calculating the factorial of 100 would overflow a long, but BigInteger handles it with ease.
import java.math.BigInteger;
public class FactorialCalculator {
public static BigInteger factorial(int n) {
if (n < 0) {
throw new IllegalArgumentException("Factorial is not defined for negative numbers.");
}
BigInteger result = BigInteger.ONE; // Start with 1
for (int i = 2; i <= n; i++) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
public static void main(String[] args) {
int number = 50;
BigInteger fact = factorial(number);
System.out.println("The factorial of " + number + " is:");
System.out.println(fact); // Prints the huge number
System.out.println("Number of digits: " + fact.toString().length());
}
}
Performance Considerations
- Slower than Primitives: Because
BigIntegeris an object and its operations involve more complex logic (like handling arrays of digits), it is significantly slower than using primitive types likeintorlong. - Memory Usage: A
BigIntegeruses more memory than a primitivelong. - Use Primitives When Possible: Only use
BigIntegerwhen you absolutely need to handle numbers that exceed the range oflong. For all other cases, stick to primitives for better performance.
Summary Table
| Task | Primitive long |
BigInteger |
|---|---|---|
| Declaration | long num = 1234567890L; |
BigInteger num = new BigInteger("12345678901234567890"); |
| Addition | num1 + num2 |
num1.add(num2) |
| Subtraction | num1 - num2 |
num1.subtract(num2) |
| Multiplication | num1 * num2 |
num1.multiply(num2) |
| Division | num1 / num2 |
num1.divide(num2) |
| Comparison | num1 < num2 |
num1.compareTo(num2) < 0 |
| Size Limit | 64 bits | Limited only by memory |
