Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rounding with DecimalFormat in Java

Let's look at the following statements in Java.

System.out.println(new DecimalFormat("0").format(2.4)); //returns 2

System.out.println(new DecimalFormat("0").format(2.5)); //returns 2  <---Concentrate here
System.out.println(Math.round(2.5));                    //returns 3

System.out.println(new DecimalFormat("0").format(2.6)); //returns 3
System.out.println(new DecimalFormat("0").format(3.5)); //returns 4

In the above statements, all other cases are obvious except the following.

System.out.println(new DecimalFormat("0").format(2.5));

It should return 3 but it returns 2. How?

like image 284
Lion Avatar asked Apr 13 '12 16:04

Lion


People also ask

What is the use of DecimalFormat in Java?

You can use the DecimalFormat class to format decimal numbers into locale-specific strings. This class allows you to control the display of leading and trailing zeros, prefixes and suffixes, grouping (thousands) separators, and the decimal separator.

How do you round off decimals in Java?

The decimal number can be rounded by the inbuilt format() method supported by Java. Syntax: System. out.

How do you round a float in Java?

You can round any floating-point numbers in Java unto n places By using either Math. round(), BigDecimal, or DecimalFormat. I personally prefer to use BigDecimal to round any number in Java because of it's convenient API and support of multiple Rounding modes.

Is Java DecimalFormat thread safe?

DecimalFormat isn't thread-safe, thus we should pay special attention when sharing the same instance between threads.


2 Answers

The default rounding mode of DecimalFormat is RoundingMode.HALF_EVEN. This means that it rounds up, or rounds down if the number is nearer to the next neighbour. When the number is exactly between two neighbours (in your case, 2 and 3), it rounds to the nearest even number (in your case, 2).

As you can see, when you tried it with 3.5, it rounded to 4.

If you want the more "intuitive" behaviour, known as “schoolhouse rounding” as it is often taught to children, use RoundingMode.HALF_UP.

setRoundingMode(RoundingMode.HALF_UP)

If the number is exactly between two neighbours, HALF_UP will always round upwards.

like image 173
Jon Bright Avatar answered Oct 03 '22 08:10

Jon Bright


This is intentional behavior. From the documentation:

Rounding

DecimalFormat uses half-even rounding (see ROUND_HALF_EVEN) for formatting.

About ROUND_HALF_EVEN:

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.

This is also known as banker's rounding.

Math.Round on the other hand uses the following formula, which is "normal" rounding:

(long)Math.floor(a + 0.5d)
like image 42
mellamokb Avatar answered Oct 03 '22 08:10

mellamokb