Key takeaways
Java's primitive data types have fixed sizes and ranges, making them unsuitable for large numbers, as they can lead to overflow.
Adding values that exceed the maximum limits of
int
andlong
can result in incorrect, negative values due to overflow, highlighting the need for more flexible solutions.The
BigInteger
class allows the processing of arbitrarily large integers without overflow and supports a variety of arithmetic operations methods that will enable precise calculations on large numbers.
When programming in Java, we encounter scenarios where we must handle large numbers, such as calculating financial transactions with high precision or performing complex scientific computations. Java provides a mechanism to handle these efficiently.
This Answer will walk you through the basics of handling large numbers.
Let's start by discussing primitive data types that hold numerical values. We'll look at their sizes and limits, and then see how Java deals with big integers. This will help you understand how to calculate big numbers precisely and efficiently.
Primitive data types are the data types available within a language. They are predefined by the language and named by a keyword. Common primitive types in Java include int
, long
, float
, double
, char
, byte
, short
, and boolean
.
Data types | Size (bits) | Range |
| 8 | -128 to 127 |
| 16 | -32,768 to 32,767 |
| 32 | -231 to 231-1 |
| 64 | -263 to 263-1 |
| 32 | 1.4e-045 to 3.4e+308 |
| 64 | 4.9e-324 to 1.8e+308 |
| 16 | 0 to 65,535 |
| 1 | true or false |
While these types come with certain limitations that programmers need to be aware of:
Each primitive data type has a fixed size, determining the range of values it can represent.
For example, an int
in Java is a long
is a
Primitive data types are not flexible in terms of size.
We cannot adjust their size to fit the needs of the application. For instance, if we need a number larger than a long
can hold, we would need to use a different approach, such as using the BigInteger
class in Java.
Here is an example that illustrates the concept of overflow with int
and long
data types in Java:
public class main {public static void main(String[] args) {// Example of int overflowint largeInt = Integer.MAX_VALUE; // Maximum value an int can holdSystem.out.println("Integer.MAX_VALUE: " + largeInt);// This will overflowlargeInt = largeInt + 1;System.out.println("After overflow, int: " + largeInt); // Incorrect value due to overflow// Example of long overflowlong largeLong = Long.MAX_VALUE; // Maximum value a long can holdSystem.out.println("Long.MAX_VALUE: " + largeLong);// This will overflowlargeLong = largeLong + 1;System.out.println("After overflow, long: " + largeLong); // Incorrect value due to overflow}}
Line 4: We define an int
variable largeInt
and assign it the maximum value an int
can hold using Integer.MAX_VALUE
.
Line 8: We then add largeInt
, which causes an overflow, resulting in an incorrect, negative value.
Line 12: We define a long
variable largeLong
and assign it the maximum value of a long
can hold using Long.MAX_VALUE
.
Line 16: Adding largeLong
also causes an overflow, resulting in an incorrect, negative value.
BigInteger
to handle large numbersBigInteger
does not have a fixed size. It can grow to accommodate any integer value as long as there is enough memory available. It handles big values by using arrays of integers to represent the number.
Let's use the BigInteger
and handle these large numbers:
import java.math.BigInteger;public class main {public static void main(String[] args) {// Example of handling large numbers with BigIntegerBigInteger largeNumber = new BigInteger("9223372036854775808"); // Larger than Long.MAX_VALUESystem.out.println("BigInteger large number: " + largeNumber);// Performing arithmetic operations without overflowBigInteger anotherLargeNumber = new BigInteger("123456789012345678901234567890");BigInteger sum = largeNumber.add(anotherLargeNumber);BigInteger difference = largeNumber.subtract(anotherLargeNumber);BigInteger product = largeNumber.multiply(anotherLargeNumber);BigInteger quotient = largeNumber.divide(anotherLargeNumber);BigInteger remainder = largeNumber.remainder(anotherLargeNumber);System.out.println("Sum: " + sum);System.out.println("Difference: " + difference);System.out.println("Product: " + product);System.out.println("Quotient: " + quotient);System.out.println("Remainder: " + remainder);}}
Line 6: We create a BigInteger
variable largeNumber
initialized with a value larger than Long.MAX_VALUE
.
Lines 10–15: We demonstrate various arithmetic operations using BigInteger
methods like add, subtract, multiply, divide, and remainder.
Lines 17–21: BigInteger
can handle arbitrarily large numbers, these operations are performed without overflow, and the results are printed.
By using the BigInteger
class, we can handle very large numbers and perform arithmetic operations without worrying about overflow, which is a limitation with primitive data types like int
and long
.
Free Resources