Home  Math intro  float and double  java.util.Math  BigDecimal and BigInteger  Karatsuba's algorithm

Search this site:
Threads Database Profiling Regular expressions Random numbers Compression Exceptions C Equivalents in Java

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:

  • where numbers are required to have a large or arbitrary range (smaller than approx 1x10-307 or larger than approx 1x10307 which are the limits of the double type);
  • where numbers are required to have arbitrary precision (e.g. more than the 15 or so significant decimal figures that you get with a double);
  • where we need to be able to represent decimal numbers precisely.

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:

  • the BigInteger class allows representation of and calculations on arbitrarily large integers (whole numbers);
  • the BigDecimal class allows precise representation of any real number that can be represented precisely in decimal notation, and allows calculations on non-integers with arbitrary precision.

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:

  • we construct a number by passing a string representation of the decimal number, e.g.:
    BigDecimal amount = new BigDecimal("6.57");
    
  • we call methods such as add(), multiply(), subtract(), divide();
  • each of these methods returns a new instance of BigInteger or BigDecimal:
    BigInteger number1 = ...
    BigInteger number2 = ...
    BigInteger sum = number1.add(number2);
    

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.


Written by Neil Coffey. Copyright © Javamex UK 2011. All rights reserved. If you have any feedback on the Java collections tutorials in this section or about the content of this site in general, please leave a message on the Javamex forum.