BigDecimal: Achieving Financial Accuracy in Java

Murat
3 min readJan 12, 2023

--

When working with numerical data in programming, it’s important to choose the appropriate data type to represent that data. Java provides several options for working with numerical data, including the double and BigDecimal data types.

While both data types can be used to represent decimal numbers, they have distinct differences and are suited for different use cases.

The double data type is a double-precision 64-bit IEEE 754 floating point, which means it has 15–17 significant digits of precision. It is often used for scientific and engineering calculations, as well as in financial applications where a high degree of precision is not required.

However, the double data type can lead to unexpected results when used in financial calculations due to the way it handles decimal values. Because of the way that floating-point arithmetic works, some decimal values cannot be represented exactly using a double, leading to small inaccuracies.

0.1 + 0.2 NOT EQUAL TO 0.3!

For example, in Java, 0.1 and 0.2 are represented as double values. However, these values cannot be represented exactly as a binary fraction, which is the way that floating-point numbers are represented in a computer’s memory. Therefore, the values of 0.1 and 0.2 are approximations of the actual decimal value.

When you add 0.1 and 0.2 together, you are adding these approximated values, which results in an approximation of the expected sum, 0.3. In most cases, this approximation is so close to the actual value that the difference is not noticeable.

However, in some cases, the approximation can lead to unexpected results. For example, the following code snippet:

double num1 = 0.1;
double num2 = 0.2;
double sum= num1+num2;
if (sum == 0.3) {
System.out.println("Equal result is: "+sum);
} else {
System.out.println("Not Equal result is: "+sum);
}

Will output “Not Equal result is: 0.30000000000000004”

Because the approximation of the sum of 0.1 and 0.2 is not exactly equal to 0.3.

The BigDecimal class, on the other hand, is a more suitable choice for financial and monetary calculations. It provides arbitrary-precision decimal arithmetic, meaning it can represent decimal values exactly without the inaccuracies that can occur with double.

For example, consider the following code snippet where we are trying to calculate the total price of an item:

BigDecimal num1 = new BigDecimal("0.1");
BigDecimal num2 = new BigDecimal("0.2");
BigDecimal sum= num1.add(num2);
if (sum.equals(new BigDecimal("0.3"))) {
System.out.println("Equal result is: "+sum);
} else {
System.out.println("Not Equal result is: "+sum);
}

Will output “Equal result is: 0.3”

Why Do I need Double and Float Then?

The main downside of using the BigDecimal class in Java is that it can be slower and use more memory than other data types such as double. This is because the BigDecimal class stores decimal numbers as a string and uses arbitrary-precision decimal arithmetic, which requires more memory and processing power to perform operations.

Another downside of the BigDecimal class is that it is less convenient to use than other data types. For example, when working with BigDecimal, you need to use its methods for performing arithmetic operations instead of using standard mathematical operators.

Additionally, the BigDecimal class is not natively supported by all platforms and hardware, which can also affect performance.

Conclusion

While the BigDecimal class is a suitable choice for financial and monetary calculations where a high degree of precision is required, it has some downsides such as performance and memory consumption, and it is less convenient to use than other data types. It is important to consider the specific requirements of your application and the trade-offs between precision and performance before choosing to use the BigDecimal class.

Some Notes About BigDecimal:

  • BigDecimal is an immutable data type. So every method of this class should be thread safe.
  • A BigDecimal consists of a random precision integer unscaled value and a 32-bit integer scale.

--

--

Murat
Murat

No responses yet