在java中如何将一个数舍入到小数点后n位

yhuiod9q  于 2021-07-03  发布在  Java
关注(0)|答案(23)|浏览(332)

我想要的是一个将double转换成字符串的方法,它使用half-up方法进行四舍五入-也就是说,如果要四舍五入的小数是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中实现这一点的最佳方法是什么?

7cjasjjr

7cjasjjr1#

您也可以使用

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

以确保有尾随的0。

iqjalb3h

iqjalb3h2#

假设你有

double d = 9232.129394d;

你可以用 BigDecimal ```
BigDecimal bd = new BigDecimal(d).setScale(2, RoundingMode.HALF_EVEN);
d = bd.doubleValue();

或者没有bigdecimal

d = Math.round(d*100)/100.0d;

两种解决方案 `d == 9232.13` 
8tntrjer

8tntrjer3#

如果你用的是 DecimalFormat 转换 doubleString ,非常简单:

DecimalFormat formatter = new DecimalFormat("0.0##");
formatter.setRoundingMode(RoundingMode.HALF_UP);

double num = 1.234567;
return formatter.format(num);

有几个 RoundingMode 要从中选择的枚举值,具体取决于所需的行为。

yzxexxkh

yzxexxkh4#

以下是要将结果作为字符串时可以使用的内容的摘要:
decimalformat#setroundingmode():

DecimalFormat df = new DecimalFormat("#.#####");
df.setRoundingMode(RoundingMode.HALF_UP);
String str1 = df.format(0.912385)); // 0.91239

bigdecimal#设置刻度()

String str2 = new BigDecimal(0.912385)
    .setScale(5, BigDecimal.ROUND_HALF_UP)
    .toString();

下面是一个建议,你可以使用哪些库如果你想 double 因此。不过,我不建议将其用于字符串转换,因为double可能无法准确表示您想要的内容(请参见此处示例):
apache commons数学的精度

double rounded = Precision.round(0.912385, 5, BigDecimal.ROUND_HALF_UP);

colt函数

double rounded = Functions.round(0.00001).apply(0.912385)

来自weka的utils

double rounded = Utils.roundDouble(0.912385, 5)
swvgeqrz

swvgeqrz5#

您可以使用以下实用方法-

public static double round(double valueToRound, int numberOfDecimalPlaces)
{
    double multipicationFactor = Math.pow(10, numberOfDecimalPlaces);
    double interestedInZeroDPs = valueToRound * multipicationFactor;
    return Math.round(interestedInZeroDPs) / multipicationFactor;
}
y0u0uwnf

y0u0uwnf6#

试试这个:org.apache.commons.math3.util.precision.round(double x,int scale)
请参见:http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/precision.html
apache commons数学库主页为:http://commons.apache.org/proper/commons-math/index.html
该方法的内部实现是:

public static double round(double x, int scale) {
    return round(x, scale, BigDecimal.ROUND_HALF_UP);
}

public static double round(double x, int scale, int roundingMethod) {
    try {
        return (new BigDecimal
               (Double.toString(x))
               .setScale(scale, roundingMethod))
               .doubleValue();
    } catch (NumberFormatException ex) {
        if (Double.isInfinite(x)) {
            return x;
        } else {
            return Double.NaN;
        }
    }
}
knsnq2tg

knsnq2tg7#

new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);

会给你一个 BigDecimal . 要想摆脱困境,就叫它吧 BigDecimaltoString 方法,或 toPlainString 方法用于Java5+的纯格式字符串。
示例程序:

package trials;
import java.math.BigDecimal;

public class Trials {

    public static void main(String[] args) {
        int yourScale = 10;
        System.out.println(BigDecimal.valueOf(0.42344534534553453453-0.42324534524553453453).setScale(yourScale, BigDecimal.ROUND_HALF_UP));
    }
4ioopgfo

4ioopgfo8#

假设 value 是一个 double ,您可以执行以下操作:

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

那是5位数的精度。零的数目表示小数的数目。

xqnpmsa8

xqnpmsa89#

为此,我们可以使用此格式化程序:

DecimalFormat df = new DecimalFormat("#.00");
 String resultado = df.format(valor)

或:

DecimalFormat df = new DecimalFormat("0.00"); :

使用此方法始终获取两个小数:

private static String getTwoDecimals(double value){
      DecimalFormat df = new DecimalFormat("0.00"); 
      return df.format(value);
    }

定义此值:

91.32
5.22
11.5
1.2
2.6

使用该方法我们可以得到以下结果:

91.32
5.22
11.50
1.20
2.60

在线演示。

w7t8yxp5

w7t8yxp510#

我来这里只是想要一个简单的答案,关于如何舍入一个数字。这是一个补充答案,以提供这一点。

如何在java中对数字进行四舍五入

最常见的情况是使用 Math.round() .

Math.round(3.7) // 4

数字四舍五入到最接近的整数。一 .5 值向上舍入。如果需要不同的舍入行为,可以使用其他数学函数之一。请参见下面的比较。

圆形

如上所述,这四舍五入到最接近的整数。

xe55xuns

xe55xuns11#

如果您真的希望十进制数用于计算(而不仅仅是用于输出),请不要使用基于二进制的浮点格式,如double。

Use BigDecimal or any other decimal-based format.

我确实使用bigdecimal进行计算,但请记住,它取决于所处理的数字的大小。在我的大多数实现中,我发现从double或integer到long的解析足以进行大量计算。
事实上,我最近最近使用了parsed to long来获得准确表示(与十六进制结果相反)的语法,以便在gui中获得准确表示(与十六进制结果相反)的结果,在一个gui中使用一个用于数字的gui中获得准确表示(与数字大小一样大的数字的gui中,如大小为如大小大小大小如如如如(\3535日日\ \3535\\35日日\35日日\ \35日\ \35日\ \35日\ \35日\ \35日\ \35日\ \35日\ \35日\ \35日\ \ \ \35日\ \ \35日\ \ \35日\ \ \35日\ \ \ \35日\35日\ \35日\ \35日\ \35日\ \35日\35日\ \35日\ \35日\ \35日\ \35日\ \35日\ \35日\ \35日\ \35日\ \35日\ \35日\ \35日\ \35日\35字符(例如)。

kqhtkvqz

kqhtkvqz12#

以防有人还需要帮助。这个解决方案对我非常有效。

private String withNoTrailingZeros(final double value, final int nrOfDecimals) {
return new BigDecimal(String.valueOf(value)).setScale(nrOfDecimals,  BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();

}

返回一个 String 具有所需的输出。

nue99wik

nue99wik13#

下面的代码片段显示了如何显示n个数字。诀窍是将变量pp设置为1,后跟n个零。在下面的示例中,变量pp值有5个零,因此将显示5位数字。

double pp = 10000;

double myVal = 22.268699999999967;
String needVal = "22.2687";

double i = (5.0/pp);

String format = "%10.4f";
String getVal = String.format(format,(Math.round((myVal +i)*pp)/pp)-i).trim();
s2j5cfk0

s2j5cfk014#

使用 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;

要四舍五入,减去精度。

rqcrx0a6

rqcrx0a615#

@milhous:舍入的十进制格式非常好:
您也可以使用

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

以确保有尾随的0。
我要补充的是,这种方法非常善于提供一种实际的数字舍入机制——不仅在视觉上,而且在处理时也是如此。
假设:必须在gui程序中实现舍入机制。要更改结果输出的准确性/精度,只需更改插入符号格式(即在括号内)。以便:

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

将作为输出返回: 0.912385 ```
DecimalFormat df = new DecimalFormat("#0.#####");
df.format(0.912385);

将作为输出返回: `0.91239` ```
DecimalFormat df = new DecimalFormat("#0.####");
df.format(0.912385);

将作为输出返回: 0.9124 [编辑:如果插入符号格式类似(“#0.#################)”),并且为了参数的缘故,您输入了一个小数,例如3.1415926,decimalformat不会产生任何垃圾(例如尾随的零),并且将返回: 3.1415926 .. 如果你是那样的话。诚然,对于某些开发人员来说,它有点冗长——但是,嘿,它在处理过程中内存占用很低,而且很容易实现。]
所以本质上,decimalformat的美妙之处在于它同时处理字符串的外观——以及舍入精度集的级别。因此:一个代码实现的代价可以带来两个好处

相关问题