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.
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.
Top Architecture Tech Stack
Sharing Java and Python tech insights, with occasional practical development tool tips.
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.