我想要的是一种将双精度转换为字符串的方法,该字符串使用半向上舍入方法进行舍入-即,如果要舍入的小数为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中实现这一点的最佳方法是什么?


当前回答

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

Use BigDecimal or any other decimal-based format.

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

事实上,我已经最近使用解析为Long以获得准确的表示(与十六进制结果相反)在GUI中,对于大小为#############字符的数字(作为示例)。

其他回答

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

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

}

返回具有所需输出的字符串。

简洁的解决方案:

   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提供此服务。

编辑:添加圆括号。将整个结果强制加倍,而不仅仅是第一个参数!

我的答案是:

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

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

一种简单的比较方法,如果小数位数有限。我们可以使用Casting来代替DecimalFormat、Math或BigDecimal!

这是样品,

public static boolean threeDecimalPlaces(double value1, double value2){
    boolean isEqual = false;
    // value1 = 3.1756 
    // value2 = 3.17
    //(int) (value1 * 1000) = 3175
    //(int) (value2 * 1000) = 3170

    if ((int) (value1 * 1000) == (int) (value2 * 1000)){
        areEqual = true;
    }

    return isEqual;
}

假设值是双倍的,您可以执行以下操作:

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

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