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
intandlongcan result in incorrect, negative values due to overflow, highlighting the need for more flexible solutions.The
BigIntegerclass 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