BackendBench
Coffee
Free tool

BigDecimal rounding explorer

Compare all eight RoundingModes side by side, and see the exact decimal value hiding inside a double.

RoundingModesetScale resultRule

Inside the number

The exact value of a double

Java

Understand BigDecimal rounding before it costs money

BigDecimal is how Java handles money and any decimal arithmetic that must be exact, and its rounding behaviour is a classic source of off-by-a-cent bugs. There are eight rounding modes, and they differ in exactly the cases people forget to test: negative numbers and values that fall exactly halfway between two candidates.

Enter a number and a scale (the number of digits after the decimal point) and the table shows the result of setScale in every mode: UP and DOWN round away from or toward zero, CEILING and FLOOR round toward positive or negative infinity, HALF_UP, HALF_DOWN and HALF_EVEN decide ties differently, and UNNECESSARY throws if any rounding would be needed. Try 2.5, -2.5, 0.125 and 2.675 to see the differences. The page also expands a double into the exact decimal value that new BigDecimal(double) produces, which explains why 0.1 + 0.2 is not 0.3, and takes a decimal apart into unscaled value, scale and precision, showing why equals and compareTo disagree.

Rules of thumb

The calculations use arbitrary-precision integers and follow the semantics of the Java documentation. They run in your browser.

Frequently asked questions

Which RoundingMode should I use for money?

HALF_UP is the usual rule taught in school and required by many tax and invoicing rules. HALF_EVEN (banker's rounding) avoids a systematic upward bias over many operations and is the default of DecimalFormat. Check what your regulation or accounting standard demands, and use the same mode everywhere.

Why does new BigDecimal(0.1) print so many digits?

The double 0.1 is not exactly one tenth; it is the nearest binary fraction, 0.1000000000000000055511151231257827021181583404541015625. new BigDecimal(double) shows that exact value. Use BigDecimal.valueOf(0.1) or new BigDecimal("0.1") to get 0.1.

Why is 2.0 not equal to 2.00 in BigDecimal?

equals() compares both value and scale, so 2.0 (scale 1) and 2.00 (scale 2) are different. compareTo() compares only the numeric value and returns 0. Use compareTo for numeric equality, or stripTrailingZeros() before equals (and in a HashMap).

What happens when I divide without a rounding mode?

a.divide(b) throws ArithmeticException ("Non-terminating decimal expansion") if the exact quotient has infinitely many digits, as for 1 divided by 3. Pass a scale and RoundingMode, or a MathContext.

More tools you might need