# How to round a number to n decimal places in Java

## How to round a number to n decimal places in Java

### 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?

### Accepted 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.

Read more... Read less...

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.

```
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));
}
```

You can also use the

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

to make sure you have the trailing 0's.

As some others have noted, the correct answer is to use either `DecimalFormat`

or `BigDecimal`

. Floating-point doesn't *have* decimal places so you cannot possibly round/truncate to a specific number of them in the first place. You have to work in a decimal radix, and that is what those two classes do.

I am posting the following code as a counter-example to all the answers in this thread and indeed all over StackOverflow (and elsewhere) that recommend multiplication followed by truncation followed by division. It is incumbent on advocates of this technique to explain why the following code produces the wrong output in over 92% of cases.

```
public class RoundingCounterExample
{
static float roundOff(float x, int position)
{
float a = x;
double temp = Math.pow(10.0, position);
a *= temp;
a = Math.round(a);
return (a / (float)temp);
}
public static void main(String[] args)
{
float a = roundOff(0.0009434f,3);
System.out.println("a="+a+" (a % .001)="+(a % 0.001));
int count = 0, errors = 0;
for (double x = 0.0; x < 1; x += 0.0001)
{
count++;
double d = x;
int scale = 2;
double factor = Math.pow(10, scale);
d = Math.round(d * factor) / factor;
if ((d % 0.01) != 0.0)
{
System.out.println(d + " " + (d % 0.01));
errors++;
}
}
System.out.println(count + " trials " + errors + " errors");
}
}
```

Output of this program:

```
10001 trials 9251 errors
```

**EDIT:** To address some comments below I redid the modulus part of the test loop using `BigDecimal`

and `new MathContext(16)`

for the modulus operation as follows:

```
public static void main(String[] args)
{
int count = 0, errors = 0;
int scale = 2;
double factor = Math.pow(10, scale);
MathContext mc = new MathContext(16, RoundingMode.DOWN);
for (double x = 0.0; x < 1; x += 0.0001)
{
count++;
double d = x;
d = Math.round(d * factor) / factor;
BigDecimal bd = new BigDecimal(d, mc);
bd = bd.remainder(new BigDecimal("0.01"), mc);
if (bd.multiply(BigDecimal.valueOf(100)).remainder(BigDecimal.ONE, mc).compareTo(BigDecimal.ZERO) != 0)
{
System.out.println(d + " " + bd);
errors++;
}
}
System.out.println(count + " trials " + errors + " errors");
}
```

Result:

```
10001 trials 4401 errors
```

Suppose you have

```
double d = 9232.129394d;
```

you can use `BigDecimal`

```
BigDecimal bd = new BigDecimal(d).setScale(2, RoundingMode.HALF_EVEN);
d = bd.doubleValue();
```

or without BigDecimal

```
d = Math.round(d*100)/100.0d;
```

with both solutions `d == 9232.13`