Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rounding Bigdecimal values with 2 Decimal Places

I want a function to convert Bigdecimal 10.12 for 10.12345 and 10.13 for 10.12556. But no function is satisfying both conversion in same time.Please help to achieve this.

Below is what I tried.
With value 10.12345:

BigDecimal a = new BigDecimal("10.12345");  a.setScale(2, BigDecimal.ROUND_UP) a.setScale(2, BigDecimal.ROUND_CEILING) a.setScale(2, BigDecimal.ROUND_DOWN) a.setScale(2, BigDecimal.ROUND_FLOOR) a.setScale(2, BigDecimal.ROUND_HALF_DOWN) a.setScale(2, BigDecimal.ROUND_HALF_EVEN) a.setScale(2, BigDecimal.ROUND_HALF_UP) 

Output :

10.12345::10.13 10.12345::10.13 10.12345::10.12 10.12345::10.12 10.12345::10.12 10.12345::10.12 10.12345::10.12 

With value 10.12556:

BigDecimal b = new BigDecimal("10.12556");  b.setScale(2, BigDecimal.ROUND_UP) b.setScale(2, BigDecimal.ROUND_CEILING) b.setScale(2, BigDecimal.ROUND_DOWN) b.setScale(2, BigDecimal.ROUND_FLOOR) b.setScale(2, BigDecimal.ROUND_HALF_DOWN) b.setScale(2, BigDecimal.ROUND_HALF_EVEN) b.setScale(2, BigDecimal.ROUND_HALF_UP) 

Output :

10.12556::10.13 10.12556::10.13 10.12556::10.12 10.12556::10.12 10.12556::10.12 10.12556::10.12 10.12556::10.12 
like image 369
sunleo Avatar asked Mar 24 '14 12:03

sunleo


People also ask

How do you round BigDecimal numbers?

You can use setScale() to reduce the number of fractional digits to zero. Assuming value holds the value to be rounded: BigDecimal scaled = value. setScale(0, RoundingMode.

Does BigDecimal have decimal places?

Immutable, arbitrary-precision signed decimal numbers. A BigDecimal consists of an arbitrary precision integer unscaled value and a 32-bit integer scale. If zero or positive, the scale is the number of digits to the right of the decimal point.

How do you correct to 2 decimal places in Java?

Just use %. 2f as the format specifier. This will make the Java printf format a double to two decimal places.


2 Answers

I think that the RoundingMode you are looking for is ROUND_HALF_EVEN. From the javadoc:

Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor. Behaves as for ROUND_HALF_UP if the digit to the left of the discarded fraction is odd; behaves as for ROUND_HALF_DOWN if it's even. Note that this is the rounding mode that minimizes cumulative error when applied repeatedly over a sequence of calculations.

Here is a quick test case:

BigDecimal a = new BigDecimal("10.12345"); BigDecimal b = new BigDecimal("10.12556");  a = a.setScale(2, BigDecimal.ROUND_HALF_EVEN); b = b.setScale(2, BigDecimal.ROUND_HALF_EVEN);  System.out.println(a); System.out.println(b); 

Correctly prints:

10.12 10.13 

UPDATE:

setScale(int, int) has not been recommended since Java 1.5, when enums were first introduced, and was finally deprecated in Java 9. You should now use setScale(int, RoundingMode) e.g:

setScale(2, RoundingMode.HALF_EVEN)

like image 88
Florent Bayle Avatar answered Sep 18 '22 13:09

Florent Bayle


Add 0.001 first to the number and then call setScale(2, RoundingMode.ROUND_HALF_UP)

Code example:

public static void main(String[] args) {     BigDecimal a = new BigDecimal("10.12445").add(new BigDecimal("0.001"));     BigDecimal b = a.setScale(2, BigDecimal.ROUND_HALF_UP);     System.out.println(b); } 
like image 43
Erwin Bolwidt Avatar answered Sep 20 '22 13:09

Erwin Bolwidt