Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to round a number to n decimal places in Java

What I would like is a method to convert a double to a string which rounds using the half-up method - i.e. if the decimal to be rounded is 5, it always rounds up to the next number. This is the standard method of rounding most people expect in most situations.

I also would like only significant digits to be displayed - i.e. there should not be any trailing zeroes.

I know one method of doing this is to use the String.format method:

String.format("%.5g%n", 0.912385); 

returns:

0.91239 

which is great, however it always displays numbers with 5 decimal places even if they are not significant:

String.format("%.5g%n", 0.912300); 

returns:

0.91230 

Another method is to use the DecimalFormatter:

DecimalFormat df = new DecimalFormat("#.#####"); df.format(0.912385); 

returns:

0.91238 

However as you can see this uses half-even rounding. That is it will round down if the previous digit is even. What I'd like is this:

0.912385 -> 0.91239 0.912300 -> 0.9123 

What is the best way to achieve this in Java?

like image 552
Alex Spurling Avatar asked Sep 30 '08 16:09

Alex Spurling


People also ask

How do you round a number to 4 decimal places in Java?

00 is for rounding up to 2 decimal places, if you want to round up to 3 or 4 places, just use #. 000 or #. 0000 to create DecimalFormat. To know more about formatting numbers, See How to format numbers in Java using DecimalFormat.

What is .2f in Java?

The %. 2f syntax tells Java to return your variable (value) with 2 decimal places (. 2) in decimal representation of a floating-point number (f) from the start of the format specifier (%).

How do you round to 2 decimal places in Java?

DecimalFormat(“0.00”) We can use DecimalFormat("0.00") to ensure the number always round to 2 decimal places.


2 Answers

Use setRoundingMode, set the RoundingMode explicitly to handle your issue with the half-even round, then use the format pattern for your required output.

Example:

DecimalFormat df = new DecimalFormat("#.####"); df.setRoundingMode(RoundingMode.CEILING); for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {     Double d = n.doubleValue();     System.out.println(df.format(d)); } 

gives the output:

12 123.1235 0.23 0.1 2341234.2125 

EDIT: The original answer does not address the accuracy of the double values. That is fine if you don't care much whether it rounds up or down. But if you want accurate rounding, then you need to take the expected accuracy of the values into account. Floating point values have a binary representation internally. That means that a value like 2.7735 does not actually have that exact value internally. It can be slightly larger or slightly smaller. If the internal value is slightly smaller, then it will not round up to 2.7740. To remedy that situation, you need to be aware of the accuracy of the values that you are working with, and add or subtract that value before rounding. For example, when you know that your values are accurate up to 6 digits, then to round half-way values up, add that accuracy to the value:

Double d = n.doubleValue() + 1e-6; 

To round down, subtract the accuracy.

like image 125
curtisk Avatar answered Sep 17 '22 00:09

curtisk


Assuming value is a double, you can do:

(double)Math.round(value * 100000d) / 100000d 

That's for 5 digits precision. The number of zeros indicate the number of decimals.

like image 30
asterite Avatar answered Sep 17 '22 00:09

asterite