BigDecimal and BigInteger: calculations with arbitrary precision in Java

For most everyday applications, even including various engineering applications, standard floating point calculations using the double type1, along with the utility methods of Java's java.util.Math class are sufficient for performing basic mathematical operations in Java. However, there are some cases where they are not sufficient:

A notable area where arbitrarily large numbers are required is in various cryptographic algorithms (typically asymetric algorithms such as RSA). The last point is slightly more subtle but illustrated if we perform a calculation such as the following:

double pence = 0.10d;
double total = pence * 3d;
System.out.println(total);

We might expect this to output the answer 0.3, but what we actually get is:

0.30000000000000004

The tiny error that appears is caused by the fact that the number 0.1 cannot be represented precisely in binary floating-point notation (i.e. in the representation used by float and double). Conversely, if pence is changed to 0.25, 0.50 or 0.75 (numbers which can be represented precisely because they consist of sums of powers of two) then the precise answer is printed. In certain applications, we might not want arbitrary errors to accumulate or not depending on whether the amount of pence happens to hit on particular values.

BigInteger vs BigDecimal: working with numbers with a large/arbitrary number of digits

Java provides a couple of classes in the java.math package to alleviate the limitations mentioned above:

It's important to note that "arbitrary" precision or number of digits does not mean "unlimited": it means that the number of digits in a number or number of digits of precision in a calculation is limited by memory and/or defined limits to precision that we specify. In simple cases, we use BigInteger and BigDecimal was follows:

Next: overview of operations

In the next section, we present an overview of methods for performing operations on BigDecimal and BigInteger numbers, along with information about their performance.


1. On the other hand, as mentioned previously, the float type offers quite poor precision and is best avoided.