Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java RoundingMode.UNNECESSARY: reject hidden fractional cents

Last updated: 5 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

BigDecimal.setScale with RoundingMode.UNNECESSARY succeeds only when the requested scale can represent the value exactly.

Validate a money input before posting

A two-decimal currency field can accept 47.00 but should reject 47.005 if the API forbids rounding at ingestion. UNNECESSARY turns that rule into an exception instead of silently moving value. Apply it before persisting or publishing a ledger entry.

Division may need an explicit rounding policy when shares are calculated. In contrast, validation of an externally supplied amount can require exact two-decimal representation. These are different boundaries.

Keep representation policy deliberate

Scale is part of BigDecimal.equals. After validation, normalize the stored scale if the database or equality policy expects one representation. Scale equality explains why equal numeric values can still behave differently as keys.

Working program

Java
import java.math.BigDecimal;
import java.math.RoundingMode;

public class LedgerAmountScaleGate {
    static BigDecimal cents(String input) {
        return new BigDecimal(input).setScale(2, RoundingMode.UNNECESSARY);
    }

    public static void main(String[] args) {
        System.out.println(cents("47.00"));
        try { cents("47.005"); }
        catch (ArithmeticException rejected) { System.out.println("fractional cent rejected"); }
    }
}

Output

Output
47.00
fractional cent rejected

Cost and ownership

Parsing and scaling allocate BigDecimal values proportional to the input's digits. Cap input length before parsing untrusted text. An exception is a validation signal here; it should be translated into a field-level error at the request boundary.

Common Mistakes

  • Do not round an input that the contract requires to be exact.
  • Do not treat scale validation as a substitute for input-length limits.
  • Do not use BigDecimal.equals as numeric equality without considering scale.

Read next

Java BigDecimal: decimal amounts and explicit rounding, Java BigDecimal.divide: make nonterminating quotients explicit, Java BigDecimal equality: value and scale are separate contracts, Java DecimalFormat: reject trailing input and pin the locale.

java
numeric
bigdecimal-setscale-unnecessary
Storage details