How to Round a Number to N Decimal Places in Java

。_饼干妹妹 提交于 2020-02-28 11:10:51

1. Overview

In this short article, we're going to look at how to round a number to n decimal places in Java.

2. Decimal Numbers in Java

Java provides two primitive types that can be used for storing decimal numbers: float and double. Double is the type used by default:

1
double PI = 3.1415 ;

However, both types should never be used for precise values, such as currencies. For that, and also for rounding, we can use the BigDecimal class.

3. Formatting a Decimal Number

If we just want to print a decimal number with n digits after decimal point, we can simply format the output String:

1
2
System.out.printf( "Value with 3 digits after decimal point %.3f %n" , PI);
// OUTPUTS: Value with 3 digits after decimal point 3.142

Alternatively, we can format the value with the DecimalFormat class:

1
2
DecimalFormat df = new DecimalFormat( "###.###" );
System.out.println(df.format(PI));

DecimalFormat allows us to explicitly set rounding behavior, giving more control of the output than String.format() used above.

4. Rounding Doubles with BigDecimal

To round doubles to n decimal places, we can write a helper method:

1
2
3
4
5
6
7
private static double round( double value, int places) {
     if (places < 0 ) throw new IllegalArgumentException();
 
     BigDecimal bd = new BigDecimal(Double.toString(value));
     bd = bd.setScale(places, RoundingMode.HALF_UP);
     return bd.doubleValue();
}

There is one important thing to notice in this solution – when constructing BigDecimal; we must always use BigDecimal(String) constructor. This prevents issues with representing inexact values.

We can achieve the same by using the Apache Commons Math library:

1
2
3
4
5
< dependency >
     < groupId >org.apache.commons</ groupId >
     < artifactId >commons-math3</ artifactId >
     < version >3.5</ version >
</ dependency >

The latest version can be found here.

Once the library is added to the project, we can use the Precision.round() method, which takes two arguments – value and scale:

1
Precision.round(PI, 3 );

By default, it is using the same HALF_UP rounding method as our helper method. Therefore, the results should be the same.

Note that we can change rounding behavior by passing the desired rounding method as a third parameter.

5. Rounding Doubles with DoubleRounder

DoubleRounder is a utility in the decimal4j library. It provides a fast and garbage-free method for rounding doubles from 0 to 18 decimal points.

We can get the library (the latest version can be found here) by adding the dependency to the pom.xml:

1
2
3
4
5
< dependency >
     < groupId >org.decimal4j</ groupId >
     < artifactId >decimal4j</ artifactId >
     < version >1.0.3</ version >
</ dependency >

Now, we can simply use:

1
DoubleRounder.round(PI, 3 );

However, DoubleRounder fails in a few scenarios, for example:

1
2
System.out.println(DoubleRounder.round( 256 .025d, 2 ));
// OUTPUTS: 256.02 instead of expected 256.03

6. Math.Round() Method

Another way of rounding numbers is to use Math.Round() Method.

In this case, we can control n number of decimal places by multiplying and dividing by 10^n:

1
2
3
4
public static double roundAvoid( double value, int places) {
     double scale = Math.pow( 10 , places);
     return Math.round(value * scale) / scale;
}

This method is not recommended as it's truncating the value. In many cases values are rounded incorrectly:

1
2
3
4
System.out.println(roundAvoid( 1000 .0d, 17 ));
// OUTPUTS: 92.23372036854776 !!
System.out.println(roundAvoid( 260 .775d, 2 ));
// OUTPUTS: 260.77 instead of expected 260.78

And so, this method is listed here for learning purposes only.

7. Conclusion

In this quick tutorial, we covered different techniques for rounding numbers to n decimal places.

We can simply format the output without changing the value, or we can round the variable by using a helper method. We've also covered a few libraries that deal with this problem.

The code used during the discussion can be found over on GitHub.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!