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

<

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.

以上是 HowtoRoundaNumbertoNDecimalPlacesinJava 的全部内容, 来源链接: utcz.com/z/513068.html

回到顶部