Avoid the Top 5 BigDecimal Pitfalls in Java Money Calculations

This article explains five common BigDecimal traps—including constructor precision loss, equals vs compareTo, division exceptions, string conversion quirks, and operation order—provides code examples, and recommends using the JSR‑354 Money API with Maven for safer monetary calculations in Java backend development.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Avoid the Top 5 BigDecimal Pitfalls in Java Money Calculations

Five Common BigDecimal Pitfalls

1.1 new BigDecimal() vs BigDecimal.valueOf()

When constructing from a double, new BigDecimal(0.01) yields a long binary representation, while BigDecimal.valueOf(0.01) uses Double.toString and preserves the exact decimal value.

BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = BigDecimal.valueOf(0.01);
System.out.println("bd1 = " + bd1);
System.out.println("bd2 = " + bd2);

The output shows

bd1 = 0.01000000000000000020816681711721685132943093776702880859375

and bd2 = 0.01.

1.2 Equality vs Comparison

equals

compares both value and scale, so new BigDecimal("1.0").equals(new BigDecimal("1.00")) returns false, while compareTo returns 0 because the numeric values are equal.

BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("1.00");
System.out.println(bd1.equals(bd2)); // false
System.out.println(bd1.compareTo(bd2)); // 0

1.3 Division May Throw ArithmeticException

Dividing 1.0 by 3.0 without a rounding mode throws an exception because the result has a non‑terminating decimal expansion.

BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("3.0");
a.divide(b); // throws ArithmeticException

Specify scale and rounding mode to obtain a finite result, e.g., a.divide(b, 2, RoundingMode.HALF_UP) yields 0.33.

1.4 Converting to String

BigDecimal.toString()

may use scientific notation; use toPlainString() to avoid it, or toEngineeringString() for engineering format.

BigDecimal d = BigDecimal.valueOf(12334535345456700.12345634534534578901);
System.out.println(d.toString());        // 1.23345353454567E+16
System.out.println(d.toPlainString());  // 12334535345456700.12345634534534578901

1.5 Order of Operations

Multiplication is not always commutative with BigDecimal due to rounding. The following example shows different results when division is performed before multiplication.

BigDecimal a = BigDecimal.valueOf(1.0);
BigDecimal b = BigDecimal.valueOf(3.0);
BigDecimal c = BigDecimal.valueOf(3.0);
System.out.println(a.divide(b, 2, RoundingMode.HALF_UP).multiply(c)); // 0.99
System.out.println(a.multiply(c).divide(b, 2, RoundingMode.HALF_UP)); // 1.00

Best Practices

Instead of using raw BigDecimal, wrap it with a money library such as JSR‑354 (Moneta). Add the Maven dependency:

<dependency>
    <groupId>org.javamoney</groupId>
    <artifactId>moneta</artifactId>
    <version>1.1</version>
</dependency>

Create a Money instance:

CurrencyUnit cny = Monetary.getCurrency("CNY");
Money money = Money.of(1.0, cny); // or Money.of(1.0, "CNY")

Perform arithmetic safely:

Money oneYuan = Money.of(1.0, cny);
Money threeYuan = oneYuan.add(Money.of(2.0, "CNY")); // CNY 3
Money tenYuan = oneYuan.multiply(10); // CNY 10
Money fiveFen = oneYuan.divide(2); // CNY 0.5
System.out.println(fiveFen.equals(Money.of(0.50, "CNY"))); // true

This approach adds explicit currency handling and avoids many BigDecimal pitfalls.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaprecisionBigDecimalJSR 354Money API
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

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.