3.5 Unbounded Integers
Key terms: class constant, constant case
Some languages provide integers of essentially unlimited size directly through their built-in
numeric types. Such values are represented internally as sequences of fixed-width units (usually 32-
or 64-bit chunks), with arithmetic performed by software routines that operate across those units.
Java, however, provides this capability through a library class, BigInteger.
Java does not support operator overloading, which allows classes to define the behavior of operators
on their instances, so arithmetic operations on BigInteger objects must be expressed through
method calls:
// compute (x + y) * (x - y)
z = x.add(y).multiply(x.subtract(y));
BigInteger, like String, is immutable: a call such as x.add(y) creates and
returns a new
BigInteger without modifying the object referenced by x.
3.5.1 Constructing BigIntegers
A BigInteger can be constructed from a string of digits:
String digits = in.next();
BigInteger base = new BigInteger(digits);
The scanner’s next method returns the exact character sequence entered by the user. If the
sequence contains any non-digit character (other than an optional leading sign), the constructor
throws an exception.
Scanner also provides nextBigInteger, which reads and parses the input in a single step. In
Listing 3.5.1, this method is used to obtain the base, while the exponent is read as an int with
nextInt. The exponentiation is then performed with BigInteger’s pow method, avoiding the
overflow that occurred with primitive values using Math.pow.
The printf method can format a BigInteger with %,d as if it were an int.
Listing 3.5.1 - PowerCalculator.java
package chap03.sect5;
import java.math.BigInteger;
import java.util.Scanner;
/**
* Performs unbounded integer exponentiation with a user-specified base and exponent.
*
* @author Drue Coles
*/
public class PowerCalculator {
public static void main(String[] args) {
// prompt the user and read input
System.out.print("Enter two integers (base and exponent): ");
Scanner in = new Scanner(System.in);
BigInteger base = in.nextBigInteger();
int exponent = in.nextInt();
BigInteger result = base.pow(exponent);
// format and display result as an equation
System.out.printf("%d^%d = %,d %n", base, exponent, result);
}
}
Output 3.5.1
Enter two integers (base and exponent): 2 100
2^100 = 1,267,650,600,228,229,401,496,703,205,376
In addition to string-based construction, BigInteger provides the factory method valueOf for
creating a BigInteger from a primitive integer value:
BigInteger n = BigInteger.valueOf(23);
This form is preferred because it makes the programmer’s intent explicit and aligns with a general Java convention of using factory methods to create number-like objects from primitive values. It also avoids the unnecessary creation of a string.
3.5.2 Class Constants
A class constant is an unmodifiable variable associated with a class. The Math class, for
example, defines Math.E and Math.PI, storing double approximations of the mathematical constants
e and π.
The BigInteger class defines constants representing 0, 1, 2, and 10. These provide canonical
objects for common values to avoid repeated allocation and initialization. For example:
// 2^127 - 1 is a Mersenne prime
BigInteger prime = BigInteger.TWO.pow(127).subtract(BigInteger.ONE);
System.out.printf("2^127 – 1 = %,d %n", prime);
Output
2^127 – 1 = 170,141,183,460,469,231,731,687,303,715,884,105,727
By convention, class constants are written in constant case: all capital letters with
underscores separating meaningful parts of compound names (as in MAX_VALUE). The Java API does not
always follow this convention, but it remains standard practice.