Understanding and Using Java BigDecimal for Precise Arithmetic
This article explains the purpose, constructors, common methods, formatting techniques, and exception handling of Java's BigDecimal class, providing code examples and best‑practice recommendations for performing high‑precision calculations in Java applications.
Java provides the java.math.BigDecimal class for precise arithmetic on numbers with more than 16 significant digits, which cannot be accurately represented using double or float .
1. BigDecimal Overview
BigDecimal objects must be manipulated via their methods rather than arithmetic operators; constructors are used to create instances.
2. Common Constructors
2.1 Constructors
1. BigDecimal(int) – creates an object from an integer value.
2. BigDecimal(double) – creates an object from a double value (may introduce precision issues).
3. BigDecimal(long) – creates an object from a long value.
4. BigDecimal(String) – creates an object from a string representation, preserving the exact value.
2.2 Usage Example
Example code:
BigDecimal a = new BigDecimal(0.1);
System.out.println("a values is:" + a);
System.out.println("=====================");
BigDecimal b = new BigDecimal("0.1");
System.out.println("b values is:" + b);Result:
a values is:0.1000000000000000055511151231257827021181583404541015625
=====================
b values is:0.1Analysis:
Using the double constructor can produce unexpected values because 0.1 cannot be represented exactly in binary floating‑point.
The String constructor yields the expected exact value, so it is generally recommended.
If a double must be used, prefer BigDecimal.valueOf(double) for a predictable conversion.
3. Common Methods
3.1 Arithmetic Operations
1. add(BigDecimal) – returns the sum.
2. subtract(BigDecimal) – returns the difference.
3. multiply(BigDecimal) – returns the product.
4. divide(BigDecimal) – returns the quotient (may require scale and rounding).
5. toString() – converts the value to a string.
6. doubleValue() – converts to double .
7. floatValue() – converts to float .
8. longValue() – converts to long .
9. intValue() – converts to int .
3.2 Comparison
Use compareTo(BigDecimal) to compare two values; it returns -1, 0, or 1.
int result = bigDecimal1.compareTo(bigDecimal2);
// result < 0 => first is smaller
// result == 0 => equal
// result > 0 => first is larger4. Formatting
NumberFormat can format BigDecimal values for currency, percentages, etc.
NumberFormat currency = NumberFormat.getCurrencyInstance();
NumberFormat percent = NumberFormat.getPercentInstance();
percent.setMaximumFractionDigits(3);
BigDecimal loanAmount = new BigDecimal("15000.48");
BigDecimal interestRate = new BigDecimal("0.008");
BigDecimal interest = loanAmount.multiply(interestRate);
System.out.println("贷款金额:\t" + currency.format(loanAmount));
System.out.println("利率:\t" + percent.format(interestRate));
System.out.println("利息:\t" + currency.format(interest));Result example: 贷款金额: ¥15,000.48 利率: 0.8% 利息: ¥120.00
Custom formatting method:
public static String formatToNumber(BigDecimal obj) {
DecimalFormat df = new DecimalFormat("#.00");
if (obj.compareTo(BigDecimal.ZERO) == 0) {
return "0.00";
} else if (obj.compareTo(BigDecimal.ZERO) > 0 && obj.compareTo(new BigDecimal(1)) < 0) {
return "0" + df.format(obj);
} else {
return df.format(obj);
}
}5. Common Exceptions
5.1 Division Exception
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal resultWhen dividing with a non‑terminating decimal, specify a scale and rounding mode, e.g., divide(divisor, 2, RoundingMode.HALF_UP) .
6. Summary
Use BigDecimal for calculations requiring exact precision; avoid it for simple arithmetic due to performance overhead.
Prefer the String constructor to avoid unexpected values.
BigDecimal is immutable; each operation returns a new instance, so store the result.
6.2 Utility Class Example
package com.vivo.ars.util;
import java.math.BigDecimal;
public class ArithmeticUtils {
private static final int DEF_DIV_SCALE = 10;
public static double add(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
// Additional methods for subtract, multiply, divide, round, etc.
}Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.