How to round a number to n decimal places in Java – Dev

The best answers to the question “How to round a number to n decimal places in Java” in the category Dev.

QUESTION:

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?

ANSWER:

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.

ANSWER:

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.

ANSWER:

You can also use the

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

to make sure you have the trailing 0’s.

ANSWER:

new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);

will get you a BigDecimal. To get the string out of it, just call that BigDecimal‘s toString method, or the toPlainString method for Java 5+ for a plain format string.

Sample program:

package trials;
import java.math.BigDecimal;

public class Trials {

    public static void main(String[] args) {
        int yourScale = 10;
        System.out.println(BigDecimal.valueOf(0.42344534534553453453-0.42324534524553453453).setScale(yourScale, BigDecimal.ROUND_HALF_UP));
    }