Java中如何将数字四舍五入到小数点后n位

发布于 2024-07-06 06:13:19 字数 811 浏览 10 评论 0原文

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

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

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

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

returns:

0.91239

这很好,但是它总是显示小数点后 5 位的数字,即使它们不重要:

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

returns:

0.91230

另一种方法是使用DecimalFormatter

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

返回:

0.91238

但是,正如您所看到的,这使用了半偶数舍入。 也就是说,如果前一位数字是偶数,则向下舍入。 我想要的是:

0.912385 -> 0.91239
0.912300 -> 0.9123

在 Java 中实现此目的的最佳方法是什么?

What I would like is a method to convert a double to a string which rounds using the half-up method - i.e. if the decimal to be rounded is 5, it always rounds up to the next number. This is the standard method of rounding most people expect in most situations.

I also would like only significant digits to be displayed - i.e. there should not be any trailing zeroes.

I know one method of doing this is to use the String.format method:

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

returns:

0.91239

which is great, however it always displays numbers with 5 decimal places even if they are not significant:

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

returns:

0.91230

Another method is to use the DecimalFormatter:

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

returns:

0.91238

However as you can see this uses half-even rounding. That is it will round down if the previous digit is even. What I'd like is this:

0.912385 -> 0.91239
0.912300 -> 0.9123

What is the best way to achieve this in Java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

我不吻晚风 2024-07-13 06:13:19

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

Use BigDecimal or any other decimal-based format.

我确实使用 BigDecimal 进行计算,但请记住它取决于
您正在处理的数字。 在我的大多数实现中,我发现从 double 或
整数到 Long 足以进行非常大的数字计算。

事实上,我已经
最近使用 parsed-to-Long 来获得准确的表示(而不是十六进制结果)
在 GUI 中,对于像 ################################### 个字符一样大的数字(作为
例子)。

If you really want decimal numbers for calculation (and not only for output), do not use a binary-based floating point format like double.

Use BigDecimal or any other decimal-based format.

I do use BigDecimal for calculations, but bear in mind it is dependent on the size of
numbers you're dealing with. In most of my implementations, I find parsing from double or
integer to Long is sufficient enough for very large number calculations.

In fact, I've
recently used parsed-to-Long to get accurate representations (as opposed to hex results)
in a GUI for numbers as big as ################################# characters (as an
example).

神妖 2024-07-13 06:13:19

试试这个: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;
        }
    }
}

Try this: org.apache.commons.math3.util.Precision.round(double x, int scale)

See: http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html

Apache Commons Mathematics Library homepage is: http://commons.apache.org/proper/commons-math/index.html

The internal implemetation of this method is:

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;
        }
    }
}
奢华的一滴泪 2024-07-13 06:13:19

因为我没有找到关于这个主题的完整答案,所以我整理了一个应该正确处理这个问题的类,并支持:

  • 格式化:轻松地将双精度格式格式化为具有一定小数位数的字符串
  • 解析:将格式化值解析回双精度
  • 语言环境:使用默认语言环境进行格式化和解析
  • 指数表示法:在特定阈值后开始使用指数表示法

>使用非常简单:(

在本示例中,我使用自定义语言环境)

public static final int DECIMAL_PLACES = 2;

NumberFormatter formatter = new NumberFormatter(DECIMAL_PLACES);

String value = formatter.format(9.319); // "9,32"
String value2 = formatter.format(0.0000005); // "5,00E-7"
String value3 = formatter.format(1324134123); // "1,32E9"

double parsedValue1 = formatter.parse("0,4E-2", 0); // 0.004
double parsedValue2 = formatter.parse("0,002", 0); // 0.002
double parsedValue3 = formatter.parse("3423,12345", 0); // 3423.12345

这是类

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Locale;

public class NumberFormatter {

    private static final String SYMBOL_INFINITE           = "\u221e";
    private static final char   SYMBOL_MINUS              = '-';
    private static final char   SYMBOL_ZERO               = '0';
    private static final int    DECIMAL_LEADING_GROUPS    = 10;
    private static final int    EXPONENTIAL_INT_THRESHOLD = 1000000000; // After this value switch to exponential notation
    private static final double EXPONENTIAL_DEC_THRESHOLD = 0.0001; // Below this value switch to exponential notation

    private DecimalFormat decimalFormat;
    private DecimalFormat decimalFormatLong;
    private DecimalFormat exponentialFormat;

    private char groupSeparator;

    public NumberFormatter(int decimalPlaces) {
        configureDecimalPlaces(decimalPlaces);
    }

    public void configureDecimalPlaces(int decimalPlaces) {
        if (decimalPlaces <= 0) {
            throw new IllegalArgumentException("Invalid decimal places");
        }

        DecimalFormatSymbols separators = new DecimalFormatSymbols(Locale.getDefault());
        separators.setMinusSign(SYMBOL_MINUS);
        separators.setZeroDigit(SYMBOL_ZERO);

        groupSeparator = separators.getGroupingSeparator();

        StringBuilder decimal = new StringBuilder();
        StringBuilder exponential = new StringBuilder("0.");

        for (int i = 0; i < DECIMAL_LEADING_GROUPS; i++) {
            decimal.append("###").append(i == DECIMAL_LEADING_GROUPS - 1 ? "." : ",");
        }

        for (int i = 0; i < decimalPlaces; i++) {
            decimal.append("#");
            exponential.append("0");
        }

        exponential.append("E0");

        decimalFormat = new DecimalFormat(decimal.toString(), separators);
        decimalFormatLong = new DecimalFormat(decimal.append("####").toString(), separators);
        exponentialFormat = new DecimalFormat(exponential.toString(), separators);

        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
        decimalFormatLong.setRoundingMode(RoundingMode.HALF_UP);
        exponentialFormat.setRoundingMode(RoundingMode.HALF_UP);
    }

    public String format(double value) {
        String result;
        if (Double.isNaN(value)) {
            result = "";
        } else if (Double.isInfinite(value)) {
            result = String.valueOf(SYMBOL_INFINITE);
        } else {
            double absValue = Math.abs(value);
            if (absValue >= 1) {
                if (absValue >= EXPONENTIAL_INT_THRESHOLD) {
                    value = Math.floor(value);
                    result = exponentialFormat.format(value);
                } else {
                    result = decimalFormat.format(value);
                }
            } else if (absValue < 1 && absValue > 0) {
                if (absValue >= EXPONENTIAL_DEC_THRESHOLD) {
                    result = decimalFormat.format(value);
                    if (result.equalsIgnoreCase("0")) {
                        result = decimalFormatLong.format(value);
                    }
                } else {
                    result = exponentialFormat.format(value);
                }
            } else {
                result = "0";
            }
        }
        return result;
    }

    public String formatWithoutGroupSeparators(double value) {
        return removeGroupSeparators(format(value));
    }

    public double parse(String value, double defValue) {
        try {
            return decimalFormat.parse(value).doubleValue();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return defValue;
    }

    private String removeGroupSeparators(String number) {
        return number.replace(String.valueOf(groupSeparator), "");
    }

}

Since I found no complete answer on this theme I've put together a class that should handle this properly, with support for:

  • Formatting: Easily format a double to string with a certain number of decimal places
  • Parsing: Parse the formatted value back to double
  • Locale: Format and parse using the default locale
  • Exponential notation: Start using exponential notation after a certain threshold

Usage is pretty simple:

(For the sake of this example I am using a custom locale)

public static final int DECIMAL_PLACES = 2;

NumberFormatter formatter = new NumberFormatter(DECIMAL_PLACES);

String value = formatter.format(9.319); // "9,32"
String value2 = formatter.format(0.0000005); // "5,00E-7"
String value3 = formatter.format(1324134123); // "1,32E9"

double parsedValue1 = formatter.parse("0,4E-2", 0); // 0.004
double parsedValue2 = formatter.parse("0,002", 0); // 0.002
double parsedValue3 = formatter.parse("3423,12345", 0); // 3423.12345

Here is the class:

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Locale;

public class NumberFormatter {

    private static final String SYMBOL_INFINITE           = "\u221e";
    private static final char   SYMBOL_MINUS              = '-';
    private static final char   SYMBOL_ZERO               = '0';
    private static final int    DECIMAL_LEADING_GROUPS    = 10;
    private static final int    EXPONENTIAL_INT_THRESHOLD = 1000000000; // After this value switch to exponential notation
    private static final double EXPONENTIAL_DEC_THRESHOLD = 0.0001; // Below this value switch to exponential notation

    private DecimalFormat decimalFormat;
    private DecimalFormat decimalFormatLong;
    private DecimalFormat exponentialFormat;

    private char groupSeparator;

    public NumberFormatter(int decimalPlaces) {
        configureDecimalPlaces(decimalPlaces);
    }

    public void configureDecimalPlaces(int decimalPlaces) {
        if (decimalPlaces <= 0) {
            throw new IllegalArgumentException("Invalid decimal places");
        }

        DecimalFormatSymbols separators = new DecimalFormatSymbols(Locale.getDefault());
        separators.setMinusSign(SYMBOL_MINUS);
        separators.setZeroDigit(SYMBOL_ZERO);

        groupSeparator = separators.getGroupingSeparator();

        StringBuilder decimal = new StringBuilder();
        StringBuilder exponential = new StringBuilder("0.");

        for (int i = 0; i < DECIMAL_LEADING_GROUPS; i++) {
            decimal.append("###").append(i == DECIMAL_LEADING_GROUPS - 1 ? "." : ",");
        }

        for (int i = 0; i < decimalPlaces; i++) {
            decimal.append("#");
            exponential.append("0");
        }

        exponential.append("E0");

        decimalFormat = new DecimalFormat(decimal.toString(), separators);
        decimalFormatLong = new DecimalFormat(decimal.append("####").toString(), separators);
        exponentialFormat = new DecimalFormat(exponential.toString(), separators);

        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
        decimalFormatLong.setRoundingMode(RoundingMode.HALF_UP);
        exponentialFormat.setRoundingMode(RoundingMode.HALF_UP);
    }

    public String format(double value) {
        String result;
        if (Double.isNaN(value)) {
            result = "";
        } else if (Double.isInfinite(value)) {
            result = String.valueOf(SYMBOL_INFINITE);
        } else {
            double absValue = Math.abs(value);
            if (absValue >= 1) {
                if (absValue >= EXPONENTIAL_INT_THRESHOLD) {
                    value = Math.floor(value);
                    result = exponentialFormat.format(value);
                } else {
                    result = decimalFormat.format(value);
                }
            } else if (absValue < 1 && absValue > 0) {
                if (absValue >= EXPONENTIAL_DEC_THRESHOLD) {
                    result = decimalFormat.format(value);
                    if (result.equalsIgnoreCase("0")) {
                        result = decimalFormatLong.format(value);
                    }
                } else {
                    result = exponentialFormat.format(value);
                }
            } else {
                result = "0";
            }
        }
        return result;
    }

    public String formatWithoutGroupSeparators(double value) {
        return removeGroupSeparators(format(value));
    }

    public double parse(String value, double defValue) {
        try {
            return decimalFormat.parse(value).doubleValue();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return defValue;
    }

    private String removeGroupSeparators(String number) {
        return number.replace(String.valueOf(groupSeparator), "");
    }

}
眼眸 2024-07-13 06:13:19

以防万一有人仍然需要帮助。 这个解决方案非常适合我。

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

}

返回带有所需输出的 ​​String

Just in case someone still needs help with this. This solution works perfectly for me.

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

}

returns a String with the desired output.

鹿港巷口少年归 2024-07-13 06:13:19

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

如何在 Java 中对数字进行舍入

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

Math.round(3.7) // 4

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

round

如上所述,四舍五入到最接近的整数。 .5 小数点向上舍入。 此方法返回一个int

Math.round(3.0); // 3
Math.round(3.1); // 3
Math.round(3.5); // 4
Math.round(3.9); // 4

Math.round(-3.0); // -3
Math.round(-3.1); // -3
Math.round(-3.5); // -3 *** careful here ***
Math.round(-3.9); // -4

ceil

任何十进制值向上舍入到下一个整数。 它已经达到了天花板。 此方法返回一个double

Math.ceil(3.0); // 3.0
Math.ceil(3.1); // 4.0
Math.ceil(3.5); // 4.0
Math.ceil(3.9); // 4.0

Math.ceil(-3.0); // -3.0
Math.ceil(-3.1); // -3.0
Math.ceil(-3.5); // -3.0
Math.ceil(-3.9); // -3.0

floor

任何十进制值向下舍入到下一个整数。 此方法返回一个double

Math.floor(3.0); // 3.0
Math.floor(3.1); // 3.0
Math.floor(3.5); // 3.0
Math.floor(3.9); // 3.0

Math.floor(-3.0); // -3.0
Math.floor(-3.1); // -4.0
Math.floor(-3.5); // -4.0
Math.floor(-3.9); // -4.0

rint

这很相似将小数值四舍五入到最接近的整数。 但是,与 round 不同,.5 值舍入为偶数。 此方法返回一个double

Math.rint(3.0); // 3.0
Math.rint(3.1); // 3.0
Math.rint(3.5); // 4.0 ***
Math.rint(3.9); // 4.0
Math.rint(4.5); // 4.0 ***
Math.rint(5.5); // 6.0 ***

Math.rint(-3.0); // -3.0
Math.rint(-3.1); // -3.0
Math.rint(-3.5); // -4.0 ***
Math.rint(-3.9); // -4.0
Math.rint(-4.5); // -4.0 ***
Math.rint(-5.5); // -6.0 ***

I came here just wanting a simple answer on how to round a number. This is a supplemental answer to provide that.

How to round a number in Java

The most common case is to use Math.round().

Math.round(3.7) // 4

Numbers are rounded to the nearest whole number. A .5 value is rounded up. If you need different rounding behavior than that, you can use one of the other Math functions. See the comparison below.

round

As stated above, this rounds to the nearest whole number. .5 decimals round up. This method returns an int.

Math.round(3.0); // 3
Math.round(3.1); // 3
Math.round(3.5); // 4
Math.round(3.9); // 4

Math.round(-3.0); // -3
Math.round(-3.1); // -3
Math.round(-3.5); // -3 *** careful here ***
Math.round(-3.9); // -4

ceil

Any decimal value is rounded up to the next integer. It goes to the ceiling. This method returns a double.

Math.ceil(3.0); // 3.0
Math.ceil(3.1); // 4.0
Math.ceil(3.5); // 4.0
Math.ceil(3.9); // 4.0

Math.ceil(-3.0); // -3.0
Math.ceil(-3.1); // -3.0
Math.ceil(-3.5); // -3.0
Math.ceil(-3.9); // -3.0

floor

Any decimal value is rounded down to the next integer. This method returns a double.

Math.floor(3.0); // 3.0
Math.floor(3.1); // 3.0
Math.floor(3.5); // 3.0
Math.floor(3.9); // 3.0

Math.floor(-3.0); // -3.0
Math.floor(-3.1); // -4.0
Math.floor(-3.5); // -4.0
Math.floor(-3.9); // -4.0

rint

This is similar to round in that decimal values round to the closest integer. However, unlike round, .5 values round to the even integer. This method returns a double.

Math.rint(3.0); // 3.0
Math.rint(3.1); // 3.0
Math.rint(3.5); // 4.0 ***
Math.rint(3.9); // 4.0
Math.rint(4.5); // 4.0 ***
Math.rint(5.5); // 6.0 ***

Math.rint(-3.0); // -3.0
Math.rint(-3.1); // -3.0
Math.rint(-3.5); // -4.0 ***
Math.rint(-3.9); // -4.0
Math.rint(-4.5); // -4.0 ***
Math.rint(-5.5); // -6.0 ***
梦在深巷 2024-07-13 06:13:19

我同意使用 DecimalFormat --- 或 BigDecimal 所选择的答案。

请先阅读下面的更新

但是,如果您确实想要对双精度值进行四舍五入并获得双精度值结果,则可以使用org.apache.commons.math3.util。 Precision.round(..) 如上所述。 该实现使用 BigDecimal,速度慢并且会产生垃圾。


decimal4j 中的 DoubleRounder 实用程序提供了类似但快速且无垃圾的方法库:

 double a = DoubleRounder.round(2.0/3.0, 3);
 double b = DoubleRounder.round(2.0/3.0, 3, RoundingMode.DOWN);
 double c = DoubleRounder.round(1000.0d, 17);
 double d = DoubleRounder.round(90080070060.1d, 9);
 System.out.println(a);
 System.out.println(b);
 System.out.println(c);
 System.out.println(d);

将输出

 0.667
 0.666
 1000.0
 9.00800700601E10

参见
https://github.com/tools4j/decimal4j/wiki/DoubleRounder-Utility

披露:我参与了decimal4j 项目。

更新:
正如 @iaforek 指出的那样,DoubleRounder 有时会返回违反直觉的结果。 原因是它执行数学上正确的舍入。 例如,DoubleRounder.round(256.025d, 2) 将向下舍入为 256.02,因为表示为 256.025d 的 double 值略小于有理值 256.025,因此将向下舍入。

注释:

  • 此行为与 BigDecimal(double) 构造函数非常相似(但与使用字符串构造函数的 valueOf(double) 不同) )。
  • 可以先通过双舍入步骤达到更高的精度来规避该问题,但它很复杂,我不会在这里详细介绍。

出于这些原因以及本文上面提到的所有内容,我不建议使用 DoubleRounder。

I agree with the chosen answer to use DecimalFormat --- or alternatively BigDecimal.

Please read Update below first!

However if you do want to round the double value and get a double value result, you can use org.apache.commons.math3.util.Precision.round(..) as mentioned above. The implementation uses BigDecimal, is slow and creates garbage.

A similar but fast and garbage-free method is provided by the DoubleRounder utility in the decimal4j library:

 double a = DoubleRounder.round(2.0/3.0, 3);
 double b = DoubleRounder.round(2.0/3.0, 3, RoundingMode.DOWN);
 double c = DoubleRounder.round(1000.0d, 17);
 double d = DoubleRounder.round(90080070060.1d, 9);
 System.out.println(a);
 System.out.println(b);
 System.out.println(c);
 System.out.println(d);

Will output

 0.667
 0.666
 1000.0
 9.00800700601E10

See
https://github.com/tools4j/decimal4j/wiki/DoubleRounder-Utility

Disclosure: I am involved in the decimal4j project.

Update:
As @iaforek pointed out DoubleRounder sometimes returns counterintuitive results. The reason is that it performs mathematically correct rounding. For instance DoubleRounder.round(256.025d, 2) will be rounded down to 256.02 because the double value represented as 256.025d is somewhat smaller than the rational value 256.025 and hence will be rounded down.

Notes:

  • This behaviour is very similar to that of the BigDecimal(double) constructor (but not to valueOf(double) which uses the string constructor).
  • The problem can be circumvented with a double rounding step to a higher precision first, but it is complicated and I am not going into the details here

For those reasons and everything mentioned above in this post I cannot recommend to use DoubleRounder.

你丑哭了我 2024-07-13 06:13:19

因此,在阅读了大部分答案后,我意识到其中大多数答案都不精确,事实上使用 BigDecimal 似乎是最好的选择,但如果您不明白 RoundingMode 是如何实现的/code> 有效,你将不可避免地失去精度。 我在项目中处理大数字时发现了这一点,并认为它可以帮助其他人在四舍五入数字时遇到困难。 例如。

BigDecimal bd = new BigDecimal("1363.2749");
bd = bd.setScale(2, RoundingMode.HALF_UP);
System.out.println(bd.doubleValue());

您希望得到 1363.28 作为输出,但最终会得到 1363.27,如果您不知道 RoundingMode< 是什么,这不是预期的结果/code> 正在做。 因此,查看 Oracle 文档,您将查找 RoundingMode.HALF_UP 的以下描述。

舍入模式向“最近邻居”舍入,除非两者都舍入
邻居是等距的,在这种情况下向上舍入。

因此,了解了这一点,我们意识到我们不会得到精确的舍入,除非我们想向最近的邻居舍入。 因此,为了完成足够的轮次,我们需要从 n-1 小数点循环到所需的小数位数。 例如。

private double round(double value, int places) throws IllegalArgumentException {

    if (places < 0) throw new IllegalArgumentException();

    // Cast the number to a String and then separate the decimals.
    String stringValue = Double.toString(value);
    String decimals = stringValue.split("\\.")[1];

    // Round all the way to the desired number.
    BigDecimal bd = new BigDecimal(stringValue);
    for (int i = decimals.length()-1; i >= places; i--) {
        bd = bd.setScale(i, RoundingMode.HALF_UP);
    }

    return bd.doubleValue();
}

这最终将为我们提供预期的输出,即 1363.28

So after reading most of the answers, I realized most of them won't be precise, in fact using BigDecimal seems like the best choice, but if you don't understand how the RoundingMode works, you will inevitable lose precision. I figured this out when working with big numbers in a project and thought it could help others having trouble rounding numbers. For example.

BigDecimal bd = new BigDecimal("1363.2749");
bd = bd.setScale(2, RoundingMode.HALF_UP);
System.out.println(bd.doubleValue());

You would expect to get 1363.28 as an output, but you will end up with 1363.27, which is not expected, if you don't know what the RoundingMode is doing. So looking into the Oracle Docs, you will find the following description for RoundingMode.HALF_UP.

Rounding mode to round towards "nearest neighbor" unless both
neighbors are equidistant, in which case round up.

So knowing this, we realized that we won't be getting an exact rounding, unless we want to round towards nearest neighbor. So, to accomplish an adequate round, we would need to loop from the n-1 decimal towards the desired decimals digits. For example.

private double round(double value, int places) throws IllegalArgumentException {

    if (places < 0) throw new IllegalArgumentException();

    // Cast the number to a String and then separate the decimals.
    String stringValue = Double.toString(value);
    String decimals = stringValue.split("\\.")[1];

    // Round all the way to the desired number.
    BigDecimal bd = new BigDecimal(stringValue);
    for (int i = decimals.length()-1; i >= places; i--) {
        bd = bd.setScale(i, RoundingMode.HALF_UP);
    }

    return bd.doubleValue();
}

This will end up giving us the expected output, which would be 1363.28.

温馨耳语 2024-07-13 06:13:19

如果您使用 DecimalFormatdouble 转换为 String,则非常简单:

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

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

有多个 RoundingMode 枚举值根据您需要的行为进行选择。

If you're using DecimalFormat to convert double to String, it's very straightforward:

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

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

There are several RoundingMode enum values to select from, depending upon the behaviour you require.

雨夜星沙 2024-07-13 06:13:19

如果您使用的技术具有最小的 JDK。 这是一种没有任何 Java 库的方法:

double scale = 100000;    
double myVal = 0.912385;
double rounded = (int)((myVal * scale) + 0.5d) / scale;

If you're using a technology that has a minimal JDK. Here's a way without any Java libs:

double scale = 100000;    
double myVal = 0.912385;
double rounded = (int)((myVal * scale) + 0.5d) / scale;
天气好吗我好吗 2024-07-13 06:13:19

这是我的答案:

double num = 4.898979485566356;
DecimalFormat df = new DecimalFormat("#.##");      
time = Double.valueOf(df.format(num));

System.out.println(num); // 4.89

here is my answer:

double num = 4.898979485566356;
DecimalFormat df = new DecimalFormat("#.##");      
time = Double.valueOf(df.format(num));

System.out.println(num); // 4.89
澜川若宁 2024-07-13 06:13:19

这是一个更好的函数,可以正确舍入像 1.005 这样的边缘情况。

简而言之,我们在四舍五入之前将尽可能小的浮点值(= 1 ulp;最后一位的单位)添加到数字中。 这将移动到数字之后的下一个可表示的值,远离零。

这是一个测试它的小程序:ideone.com

/**
 * Round half away from zero ('commercial' rounding)
 * Uses correction to offset floating-point inaccuracies.
 * Works symmetrically for positive and negative numbers.
 */
public static double round(double num, int digits) {

    // epsilon correction
    double n = Double.longBitsToDouble(Double.doubleToLongBits(num) + 1);
    double p = Math.pow(10, digits);
    return Math.round(n * p) / p;
}

// test rounding of half
System.out.println(round(0.5, 0));   // 1
System.out.println(round(-0.5, 0));  // -1

// testing edge cases
System.out.println(round(1.005, 2));   // 1.01
System.out.println(round(2.175, 2));   // 2.18
System.out.println(round(5.015, 2));   // 5.02

System.out.println(round(-1.005, 2));  // -1.01
System.out.println(round(-2.175, 2));  // -2.18
System.out.println(round(-5.015, 2));  // -5.02

Here is a better function that rounds edge cases like 1.005 correctly.

Simply, we add the smallest possible float value (= 1 ulp; unit in the last place) to the number before rounding. This moves to the next representable value after the number, away from zero.

This is a little program to test it: ideone.com

/**
 * Round half away from zero ('commercial' rounding)
 * Uses correction to offset floating-point inaccuracies.
 * Works symmetrically for positive and negative numbers.
 */
public static double round(double num, int digits) {

    // epsilon correction
    double n = Double.longBitsToDouble(Double.doubleToLongBits(num) + 1);
    double p = Math.pow(10, digits);
    return Math.round(n * p) / p;
}

// test rounding of half
System.out.println(round(0.5, 0));   // 1
System.out.println(round(-0.5, 0));  // -1

// testing edge cases
System.out.println(round(1.005, 2));   // 1.01
System.out.println(round(2.175, 2));   // 2.18
System.out.println(round(5.015, 2));   // 5.02

System.out.println(round(-1.005, 2));  // -1.01
System.out.println(round(-2.175, 2));  // -2.18
System.out.println(round(-5.015, 2));  // -5.02
晨敛清荷 2024-07-13 06:13:19

下面的代码片段展示了如何显示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();

The code snippet below shows how to display n digits. The trick is to set variable pp to 1 followed by n zeros. In the example below, variable pp value has 5 zeros, so 5 digits will be displayed.

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();
豆芽 2024-07-13 06:13:19

DecimalFormat 是最好的输出方式,但我不喜欢它。 我总是这样做,因为它返回双精度值。 所以我可以使用它而不仅仅是输出。

Math.round(selfEvaluate*100000d.0)/100000d.0;

或者

Math.round(selfEvaluate*100000d.0)*0.00000d1;

如果您需要大的小数位值,您可以使用 BigDecimal 代替。 无论如何 .0 很重要。 如果没有它,0.33333d5 的舍入将返回 0.33333,并且只允许 9 位数字。 没有 .0 的第二个函数存在 0.30000 返回 0.30000000000000004 的问题。

DecimalFormat is the best ways to output, but I don't prefer it. I always do this all the time, because it return the double value. So I can use it more than just output.

Math.round(selfEvaluate*100000d.0)/100000d.0;

OR

Math.round(selfEvaluate*100000d.0)*0.00000d1;

If you need large decimal places value, you can use BigDecimal instead. Anyways .0 is important. Without it the rounding of 0.33333d5 return 0.33333 and only 9 digits are allows. The second function without .0 has problems with 0.30000 return 0.30000000000000004.

爱冒险 2024-07-13 06:13:19

我像在java 8中一样使用了波纹管。它对我有用

    double amount = 1000.431;        
    NumberFormat formatter = new DecimalFormat("##.00");
    String output = formatter.format(amount);
    System.out.println("output = " + output);

输出:

output = 1000.43

I have used bellow like in java 8. it is working for me

    double amount = 1000.431;        
    NumberFormat formatter = new DecimalFormat("##.00");
    String output = formatter.format(amount);
    System.out.println("output = " + output);

Output:

output = 1000.43
幻想少年梦 2024-07-13 06:13:19

如果需要double,可以使用以下方法,

double getRandom(int decimalPoints) {
    double a = Math.random();
    int multiplier = (int) Math.pow(10, decimalPoints);
    int b = (int) (a * multiplier);
    return b / (double) multiplier;
}

例如getRandom(2)

the following method could be used if need double

double getRandom(int decimalPoints) {
    double a = Math.random();
    int multiplier = (int) Math.pow(10, decimalPoints);
    int b = (int) (a * multiplier);
    return b / (double) multiplier;
}

for example getRandom(2)

无远思近则忧 2024-07-13 06:13:19

使用 setRoundingMode,设置< code>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;

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

Use setRoundingMode, set the RoundingMode explicitly to handle your issue with the half-even round, then use the format pattern for your required output.

Example:

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

gives the output:

12
123.1235
0.23
0.1
2341234.2125

EDIT: The original answer does not address the accuracy of the double values. That is fine if you don't care much whether it rounds up or down. But if you want accurate rounding, then you need to take the expected accuracy of the values into account. Floating point values have a binary representation internally. That means that a value like 2.7735 does not actually have that exact value internally. It can be slightly larger or slightly smaller. If the internal value is slightly smaller, then it will not round up to 2.7740. To remedy that situation, you need to be aware of the accuracy of the values that you are working with, and add or subtract that value before rounding. For example, when you know that your values are accurate up to 6 digits, then to round half-way values up, add that accuracy to the value:

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

To round down, subtract the accuracy.

只有一腔孤勇 2024-07-13 06:13:19

假设 value 是一个 double,您可以这样做:

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

这是 5 位精度。 零的个数表示小数点的个数。

Assuming value is a double, you can do:

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

That's for 5 digits precision. The number of zeros indicate the number of decimals.

挽心 2024-07-13 06:13:19
new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);

将为您提供一个BigDecimal。 要从中获取字符串,只需调用 BigDecimaltoString 方法,或者调用 Java 5+ 的 toPlainString 方法以获得纯格式细绳。

示例程序:

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));
    }
new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);

will get you a BigDecimal. To get the string out of it, just call that BigDecimal's toString method, or the toPlainString method for Java 5+ for a plain format string.

Sample program:

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));
    }
反话 2024-07-13 06:13:19

您还可以使用 来

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

确保尾随 0。

You can also use the

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

to make sure you have the trailing 0's.

清风疏影 2024-07-13 06:13:19

正如其他一些人所指出的,正确的答案是使用 DecimalFormatBigDecimal。 浮点数没有小数位,因此您不可能首先舍入/截断到特定数量的小数位。 您必须使用十进制基数,这就是这两个类的作用。

我发布以下代码作为该线程中所有答案的反例,实际上整个 StackOverflow(和其他地方)都建议先乘法,然后截断,然后除法。 该技术的倡导者有责任解释为什么以下代码在超过 92% 的情况下会产生错误的输出。

public class RoundingCounterExample
{

    static float roundOff(float x, int position)
    {
        float a = x;
        double temp = Math.pow(10.0, position);
        a *= temp;
        a = Math.round(a);
        return (a / (float)temp);
    }

    public static void main(String[] args)
    {
        float a = roundOff(0.0009434f,3);
        System.out.println("a="+a+" (a % .001)="+(a % 0.001));
        int count = 0, errors = 0;
        for (double x = 0.0; x < 1; x += 0.0001)
        {
            count++;
            double d = x;
            int scale = 2;
            double factor = Math.pow(10, scale);
            d = Math.round(d * factor) / factor;
            if ((d % 0.01) != 0.0)
            {
                System.out.println(d + " " + (d % 0.01));
                errors++;
            }
        }
        System.out.println(count + " trials " + errors + " errors");
    }
}

该程序的输出:

10001 trials 9251 errors

编辑:为了解决下面的一些评论,我使用BigDecimalnew MathContext(16)重新编辑了测试循环的模数部分求模运算如下:

public static void main(String[] args)
{
    int count = 0, errors = 0;
    int scale = 2;
    double factor = Math.pow(10, scale);
    MathContext mc = new MathContext(16, RoundingMode.DOWN);
    for (double x = 0.0; x < 1; x += 0.0001)
    {
        count++;
        double d = x;
        d = Math.round(d * factor) / factor;
        BigDecimal bd = new BigDecimal(d, mc);
        bd = bd.remainder(new BigDecimal("0.01"), mc);
        if (bd.multiply(BigDecimal.valueOf(100)).remainder(BigDecimal.ONE, mc).compareTo(BigDecimal.ZERO) != 0)
        {
            System.out.println(d + " " + bd);
            errors++;
        }
    }
    System.out.println(count + " trials " + errors + " errors");
}

结果:

10001 trials 4401 errors

As some others have noted, the correct answer is to use either DecimalFormat or BigDecimal. Floating-point doesn't have decimal places so you cannot possibly round/truncate to a specific number of them in the first place. You have to work in a decimal radix, and that is what those two classes do.

I am posting the following code as a counter-example to all the answers in this thread and indeed all over StackOverflow (and elsewhere) that recommend multiplication followed by truncation followed by division. It is incumbent on advocates of this technique to explain why the following code produces the wrong output in over 92% of cases.

public class RoundingCounterExample
{

    static float roundOff(float x, int position)
    {
        float a = x;
        double temp = Math.pow(10.0, position);
        a *= temp;
        a = Math.round(a);
        return (a / (float)temp);
    }

    public static void main(String[] args)
    {
        float a = roundOff(0.0009434f,3);
        System.out.println("a="+a+" (a % .001)="+(a % 0.001));
        int count = 0, errors = 0;
        for (double x = 0.0; x < 1; x += 0.0001)
        {
            count++;
            double d = x;
            int scale = 2;
            double factor = Math.pow(10, scale);
            d = Math.round(d * factor) / factor;
            if ((d % 0.01) != 0.0)
            {
                System.out.println(d + " " + (d % 0.01));
                errors++;
            }
        }
        System.out.println(count + " trials " + errors + " errors");
    }
}

Output of this program:

10001 trials 9251 errors

EDIT: To address some comments below I redid the modulus part of the test loop using BigDecimal and new MathContext(16) for the modulus operation as follows:

public static void main(String[] args)
{
    int count = 0, errors = 0;
    int scale = 2;
    double factor = Math.pow(10, scale);
    MathContext mc = new MathContext(16, RoundingMode.DOWN);
    for (double x = 0.0; x < 1; x += 0.0001)
    {
        count++;
        double d = x;
        d = Math.round(d * factor) / factor;
        BigDecimal bd = new BigDecimal(d, mc);
        bd = bd.remainder(new BigDecimal("0.01"), mc);
        if (bd.multiply(BigDecimal.valueOf(100)).remainder(BigDecimal.ONE, mc).compareTo(BigDecimal.ZERO) != 0)
        {
            System.out.println(d + " " + bd);
            errors++;
        }
    }
    System.out.println(count + " trials " + errors + " errors");
}

Result:

10001 trials 4401 errors
叶落知秋 2024-07-13 06:13:19

假设您

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

Suppose you have

double d = 9232.129394d;

you can use BigDecimal

BigDecimal bd = new BigDecimal(d).setScale(2, RoundingMode.HALF_EVEN);
d = bd.doubleValue();

or without BigDecimal

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

with both solutions d == 9232.13

贱人配狗天长地久 2024-07-13 06:13:19

您可以使用 DecimalFormat 类。

double d = 3.76628729;

DecimalFormat newFormat = new DecimalFormat("#.##");
double twoDecimal =  Double.valueOf(newFormat.format(d));

You can use the DecimalFormat class.

double d = 3.76628729;

DecimalFormat newFormat = new DecimalFormat("#.##");
double twoDecimal =  Double.valueOf(newFormat.format(d));
青衫负雪 2024-07-13 06:13:19

Real 的 Java How-to 帖子 这个解决方案,它也兼容 Java 之前的版本1.6.

BigDecimal bd = new BigDecimal(Double.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();

更新:BigDecimal.ROUND_HALF_UP 已弃用 - 使用 RoundingMode

BigDecimal bd = new BigDecimal(Double.toString(number));
bd = bd.setScale(decimalPlaces, RoundingMode.HALF_UP);
return bd.doubleValue();

Real's Java How-to posts this solution, which is also compatible for versions before Java 1.6.

BigDecimal bd = new BigDecimal(Double.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();

UPDATE: BigDecimal.ROUND_HALF_UP is deprecated - Use RoundingMode

BigDecimal bd = new BigDecimal(Double.toString(number));
bd = bd.setScale(decimalPlaces, RoundingMode.HALF_UP);
return bd.doubleValue();
剧终人散尽 2024-07-13 06:13:19
double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;
double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;
翻身的咸鱼 2024-07-13 06:13:19

@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 的优点在于它同时处理字符串
外观——以及舍入精度设置的水平。 因此:你
以执行一种代码的价格获得两种好处。 ;)

@Milhous: the decimal format for rounding is excellent:

You can also use the

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

to make sure you have the trailing 0's.

I would add that this method is very good at providing an actual
numeric, rounding mechanism - not only visually, but also when processing.

Hypothetical: you have to implement a rounding mechanism into a GUI
program. To alter the accuracy / precision of a result output simply
change the caret format (i.e. within the brackets). So that:

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

would return as output: 0.912385

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

would return as output: 0.91239

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

would return as output: 0.9124

[EDIT: also if the caret format is like so ("#0.############") and you
enter a decimal, e.g. 3.1415926, for argument's sake, DecimalFormat
does not produce any garbage (e.g. trailing zeroes) and will return:
3.1415926 .. if you're that way inclined. Granted, it's a little verbose
for the liking of some dev's - but hey, it's got a low memory footprint
during processing and is very easy to implement.]

So essentially, the beauty of DecimalFormat is that it simultaneously handles the string
appearance - as well as the level of rounding precision set. Ergo: you
get two benefits for the price of one code implementation. ;)

空‖城人不在 2024-07-13 06:13:19

如果您希望结果为字符串,以下是您可以使用的摘要:

  1. DecimalFormat#setRoundingMode()

    DecimalFormat df = new DecimalFormat("#.#####"); 
      df.setRoundingMode(RoundingMode.HALF_UP); 
      字符串 str1 = df.format(0.912385));   // 0.91239 
      
  2. BigDecimal#setScale()

    字符串 str2 = new BigDecimal(0.912385) 
          .setScale(5, BigDecimal.ROUND_HALF_UP) 
          .toString(); 
      

如果您想要 double 结果,这里建议您可以使用哪些库。 不过,我不建议将其用于字符串转换,因为 double 可能无法准确表示您想要的内容(请参见此处):

  1. 精度 来自 Apache Commons Math

    双舍入 = Precision.round(0.912385, 5, BigDecimal.ROUND_HALF_UP); 
      
  2. Colt 的函数

    双舍入 = Functions.round(0.00001).apply(0.912385) 
      
  3. 实用工具来自Weka

    双圆角 = Utils.roundDouble(0.912385, 5) 
      

Here is a summary of what you can use if you want the result as String:

  1. DecimalFormat#setRoundingMode():

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

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

Here is a suggestion of what libraries you can use if you want double as a result. I wouldn't recommend it for string conversion, though, as double may not be able to represent what you want exactly (see e.g. here):

  1. Precision from Apache Commons Math

    double rounded = Precision.round(0.912385, 5, BigDecimal.ROUND_HALF_UP);
    
  2. Functions from Colt

    double rounded = Functions.round(0.00001).apply(0.912385)
    
  3. Utils from Weka

    double rounded = Utils.roundDouble(0.912385, 5)
    
傾城如夢未必闌珊 2024-07-13 06:13:19

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

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

You could use the following utility method-

public static double round(double valueToRound, int numberOfDecimalPlaces)
{
    double multipicationFactor = Math.pow(10, numberOfDecimalPlaces);
    double interestedInZeroDPs = valueToRound * multipicationFactor;
    return Math.round(interestedInZeroDPs) / multipicationFactor;
}
眼睛会笑 2024-07-13 06:13:19

简洁的解决方案:

   public static double round(double value, int precision) {
      int scale = (int) Math.pow(10, precision);
      return (double) (Math.round(value * scale) / scale);
  }

另请参阅https://stackoverflow.com/a/22186845/212950
感谢 jpdymond 提供此内容。

编辑:添加圆括号。 将整个结果转换为双精度,而不仅仅是第一个参数!

A succinct solution:

   public static double round(double value, int precision) {
      int scale = (int) Math.pow(10, precision);
      return (double) (Math.round(value * scale) / scale);
  }

See also, https://stackoverflow.com/a/22186845/212950
Thanks to jpdymond for offering this.

Edit: Added round brackets. Casts the whole result to double, not the first argument only!

在你怀里撒娇 2024-07-13 06:13:19

您可以使用 BigDecimal

BigDecimal value = new BigDecimal("2.3");
value = value.setScale(0, RoundingMode.UP);
BigDecimal value1 = new BigDecimal("-2.3");
value1 = value1.setScale(0, RoundingMode.UP);
System.out.println(value + "n" + value1);

参考:http://www.javabeat.net/precise -使用舍入模式枚举的小数舍入/

You can use BigDecimal

BigDecimal value = new BigDecimal("2.3");
value = value.setScale(0, RoundingMode.UP);
BigDecimal value1 = new BigDecimal("-2.3");
value1 = value1.setScale(0, RoundingMode.UP);
System.out.println(value + "n" + value1);

Refer: http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/

爱,才寂寞 2024-07-13 06:13:19

为了实现这一点,我们可以使用此格式化程序:

 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

在线演示。

To achieve this we can use this formatter:

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

or:

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

Use this method to get always two decimals:

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

Defining this values:

91.32
5.22
11.5
1.2
2.6

Using the method we can get this results:

91.32
5.22
11.50
1.20
2.60

demo online.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文