Fundamentals 15 min read

Understanding and Using Java BigDecimal for Precise Arithmetic

This article introduces Java's BigDecimal class, explains its purpose for high-precision arithmetic beyond double's limits, details constructors, common methods, formatting, comparison, and exception handling, and provides practical code examples and a utility class for accurate mathematical operations.

Architect
Architect
Architect
Understanding and Using Java BigDecimal for Precise Arithmetic

1. Overview of BigDecimal

Java provides the java.math.BigDecimal class for precise calculations with numbers that exceed the 16‑digit precision of double . While double can handle up to 16 significant digits, many applications require higher precision, which BigDecimal supplies.

2. Common Constructors

BigDecimal(int) – creates an instance from an int value.

BigDecimal(double) – creates an instance from a double value (may introduce unexpected precision errors).

BigDecimal(long) – creates an instance from a long value.

BigDecimal(String) – creates an instance from a string representation (recommended for exact values).

2.1 Usage Example

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.1

Analysis:

The BigDecimal(double) constructor inherits the binary representation of the double, so new BigDecimal(0.1) does not equal exactly 0.1.

The BigDecimal(String) constructor creates an exact value, so new BigDecimal("0.1") equals 0.1.

If a double must be used, prefer BigDecimal.valueOf(double) , which internally uses Double.toString(double) to avoid the unexpected precision.

3. Common Methods

add(BigDecimal) – addition.

subtract(BigDecimal) – subtraction.

multiply(BigDecimal) – multiplication.

divide(BigDecimal) – division (may throw ArithmeticException if the result is non‑terminating).

toString() – converts to a string.

doubleValue() , floatValue() , longValue() , intValue() – convert to primitive types.

3.1 Comparing Size

Use compareTo to compare two BigDecimal objects.

int result = bigDecimal1.compareTo(bigDecimal2);
// result = -1 if less, 0 if equal, 1 if greater

4. Formatting with NumberFormat

The NumberFormat class 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

5. Common Exceptions

Division that results in a non‑terminating decimal throws java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result . Resolve by specifying a scale, e.g., divide(divisor, scale) .

6. Summary

Use BigDecimal when exact decimal results are required; it is slower than double and creates immutable objects, so each operation returns a new instance. Prefer the String constructor for predictable values.

7. Recommended Utility Class

package com.vivo.ars.util;
import java.math.BigDecimal;
/**
 * Utility class for high‑precision arithmetic operations.
 */
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();
    }

    public static BigDecimal add(String v1, String v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2);
    }

    public static String add(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    // Similar methods for subtract, multiply, divide, round, remainder, compare, etc.
}

The utility demonstrates precise addition, subtraction, multiplication, division, rounding, remainder calculation, and comparison using BigDecimal .

JavaPrecisionArithmeticBigDecimalNumberFormatUtility
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.