HowtoRoundaNumbertoNDecimalPlacesinJava
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
<
>
<
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.
以上是 HowtoRoundaNumbertoNDecimalPlacesinJava 的全部内容, 来源链接: utcz.com/z/513068.html