How to Round a Number to N Decimal Places in Java – 如何在Java中把一个数字四舍五入到小数点后N位

最后修改: 2017年 6月 3日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this short tutorial, we’ll learn how to round a number to n decimal places in Java.

在这个简短的教程中,我们将学习如何在Java中把一个数字四舍五入到n小数位。

2. Decimal Numbers in Java

2.Java中的小数

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

Java提供了两种原始类型,我们可以用它们来存储十进制数字。floatdoubleDouble是默认类型。

double PI = 3.1415;

However, we should never use either type for precise values, such as currencies. For that, and also for rounding, we can use the BigDecimal class.

然而,我们不应该将这两种类型用于精确的数值,例如货币。为此,也为了四舍五入,我们可以使用BigDecimal类。

3. Formatting a Decimal Number

3.小数的格式化

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

如果我们只想打印一个小数点后有n个数字的小数,我们可以简单地将输出字符串格式化。

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:

另外,我们可以用DecimalFormat类来格式化该值。

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 the String.format() used above.

DecimalFormat允许我们明确地设置四舍五入行为,比上面使用的String.format()更能控制输出。

4. Rounding Doubles With BigDecimal

4.用BigDecimalDoubles进行舍入

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

为了将doubles四舍五入到n个小数位,我们可以写一个helper方法

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.

在这个解决方案中,有一件重要的事情需要注意;在构造BigDecimal时,我们必须始终使用BigDecimal(String)构造函数。这样可以防止出现表示不精确的值的问题。

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

我们可以通过使用Apache Commons Math库实现同样的结果。

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-math3</artifactId>
    <version>3.5</version>
</dependency>

The latest version can be found here.

最新版本可以在这里找到。

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

一旦我们将该库添加到项目中,我们就可以使用Precision.round()方法,它需要两个参数–值和刻度。

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.

默认情况下,它使用与我们的帮助方法相同的HALF_UP四舍五入方法;因此,结果应该是一样的。

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

注意,我们可以通过传递所需的四舍五入方法作为第三个参数来改变舍入行为。

5. Rounding Doubles With DoubleRounder

5.用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.

DoubleRounderdecimal4j库中的一个工具。它提供了一种快速且无垃圾的方法来对小数点后0至18位的双数进行舍入。

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

我们可以通过在pom.xml中添加依赖关系来获得该库(最新版本可以在这里)。

<dependency>
    <groupId>org.decimal4j</groupId>
    <artifactId>decimal4j</artifactId>
    <version>1.0.3</version>
</dependency>

Now we can simply use:

现在我们可以简单地使用。

DoubleRounder.round(PI, 3);

However, DoubleRounder fails in a few scenarios:

然而,DoubleRounder在一些情况下会失败。

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

6. Math.round() Method

6.Math.round()方法

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

另一种四舍五入的方法是使用 Math.Round()方法。

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

在这种情况下,我们可以通过10^n的乘法和除法来控制n的小数位数。

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:

不建议使用这种方法,因为它在截断数值。在许多情况下,数值被错误地四舍五入。

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

As a result, this method is listed here for learning purposes only.

因此,在此列出这种方法,仅供学习之用。

7. Conclusion

7.结论

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

在这篇文章中,我们介绍了将数字四舍五入到n个小数位的不同技术。

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

我们可以在不改变数值的情况下简单地对输出进行格式化,也可以通过使用辅助方法对变量进行舍入。我们还讨论了一些处理这个问题的库。

The code used in this article can be found over on GitHub.

本文中使用的代码可以在GitHub上找到over