Fundamentals 6 min read

Understanding Java BigDecimal: How It Guarantees Precision

This article explains the Java BigDecimal class, its internal fields, and how its addition method scales numbers to maintain precision, illustrated with code examples and debugging insights, concluding that BigDecimal performs arithmetic using scaled long integers to avoid precision loss.

Top Architecture Tech Stack
Top Architecture Tech Stack
Top Architecture Tech Stack
Understanding Java BigDecimal: How It Guarantees Precision

In financial applications, precise decimal calculations are essential, so Java provides the BigDecimal class. This article examines why BigDecimal can guarantee loss‑less precision.

Class Overview

The class declaration and key fields are shown, including the unscaled value (intVal), scale, precision, stringCache, and intCompact.

public class BigDecimal extends Number implements Comparable
{
    // unscaled value
    private final BigInteger intVal;
    // scale (number of digits after decimal point)
    private final int scale;
    private transient int precision;
    private transient String stringCache;
    private final transient long intCompact;
}

Example

A test method creates two BigDecimal instances and adds them, demonstrating the values assigned to the fields during debugging.

@Test
public void testBigDecimal() {
    BigDecimal bigDecimal1 = BigDecimal.valueOf(2.36);
    BigDecimal bigDecimal2 = BigDecimal.valueOf(3.5);
    BigDecimal resDecimal = bigDecimal1.add(bigDecimal2);
    System.out.println(resDecimal);
}

The addition method is inspected, showing how the scale difference determines the computation path.

/** Returns a BigDecimal whose value is (this + augend), and whose scale is max(this.scale(), augend.scale()). */
public BigDecimal add(BigDecimal augend) {
    if (this.intCompact != INFLATED) {
        if (augend.intCompact != INFLATED) {
            return add(this.intCompact, this.scale, augend.intCompact, augend.scale);
        } else {
            return add(this.intCompact, this.scale, augend.intVal, augend.scale);
        }
    } else {
        // other branches...
    }
}

For the example, the parameters are xs=236, scale1=2, ys=35, scale2=1. The method first computes the scale difference, then scales the smaller operand by a power of ten, performs long addition, and finally constructs a new BigDecimal with the appropriate scale.

private static BigDecimal add(final long xs, int scale1, final long ys, int scale2) {
    long sdiff = (long) scale1 - scale2;
    if (sdiff == 0) {
        return add(xs, ys, scale1);
    } else if (sdiff < 0) {
        int raise = checkScale(xs, -sdiff);
        long scaledX = longMultiplyPowerTen(xs, raise);
        if (scaledX != INFLATED) {
            return add(scaledX, ys, scale2);
        } else {
            // big integer path...
        }
    } else {
        // symmetric case...
    }
}

Thus, BigDecimal achieves precision by scaling numbers to long integers (or BigInteger when overflow occurs) and performing integer arithmetic, then applying the stored scale to produce the final result.

Conclusion

BigDecimal multiplies operands by powers of ten to convert them into integer form, performs exact integer addition, and uses the scale to represent the decimal point, ensuring no precision loss.

backendJavaPrecisionArithmeticBigDecimal
Top Architecture Tech Stack
Written by

Top Architecture Tech Stack

Sharing Java and Python tech insights, with occasional practical development tool tips.

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.