如何在 Java 中将数字舍入为 n 个小数位

2022-08-31 03:56:49

我想要的是一种将双精度值转换为字符串的方法,该字符串使用半上部方法进行舍入 - 即,如果要舍入的小数点为5,则它始终向上舍入到下一个数字。这是大多数人在大多数情况下期望的标准四舍五入方法。

我还希望只显示有效数字 - 即不应该有任何尾随零。

我知道这样做的一种方法是使用该方法:String.format

String.format("%.5g%n", 0.912385);

返回:

0.91239

这很好,但是它总是显示带有5个小数位的数字,即使它们不显着:

String.format("%.5g%n", 0.912300);

返回:

0.91230

另一种方法是使用:DecimalFormatter

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

返回:

0.91238

但是,如您所见,这使用半偶数舍入。也就是说,如果前一个数字是偶数,它将向下舍入。我想要的是这个:

0.912385 -> 0.91239
0.912300 -> 0.9123

在Java中实现这一目标的最佳方法是什么?


答案 1

使用 setRoundingMode,显式设置 RoundingMode 以处理半偶数倒圆角的问题,然后对所需输出使用格式模式。

例:

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

给出输出:

12
123.1235
0.23
0.1
2341234.2125

编辑:原始答案没有解决双精度值的准确性。如果你不太关心它是向上还是向下舍入,那很好。但是,如果您想要准确的舍入,则需要考虑值的预期准确性。浮点值在内部具有二进制表示形式。这意味着像 2.7735 这样的值实际上在内部没有该确切值。它可以稍大或略小。如果内部值略小,则不会向上舍入到 2.7740。要纠正这种情况,您需要了解正在使用的值的准确性,并在舍入之前添加或减去该值。例如,当您知道您的值最多精确到 6 位时,要将中途值向上舍入,请将该精度添加到值中:

Double d = n.doubleValue() + 1e-6;

要向下舍入,请减去精度。


答案 2

假设 是 ,你可以做:valuedouble

(double)Math.round(value * 100000d) / 100000d

这是为了5位精度。零数表示小数位数。