java - Jav如何将数字舍入到小数点后n

  显示原文与译文双语对照的内容

我想要的是一种方法,它将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

 

但是,就像你看到的,使用half-even舍入。 如果上一个数字是偶数,它就会颠倒。 我想要的是:


0.912385 -> 0.91239
0.912300 -> 0.9123

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

时间:

于你的必选output,使用相关 setRoundingMode,请参见链接的java doc,请将 RoundingMode 显式来处理你的问题与half-even了纸张,然后使用格式孔

假设 valuedouble,你可以执行以下操作:


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

用于 5位精度。 零表示小数位数。


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

会给你一个 BigDecimal 。 时,得到的字符串重复,只需叫它 BigDecimal的方法或者有关Java的toPlainString 方法 toString 5 + 适用于平头格式字符串。

有些人已经注意到,正确的答案是使用 DecimalFormat 或者 BigDecimal 。 在第一个 place, Floating-point不有小数位数,所以你不可能圆/截断选项可以用来特定数目的。 你必须用十进制的基数,这就是这两个类的作用。

我将下面的代码作为一个counter-example发布到这个线程中的所有答案,实际上所有的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

编辑: 我注意到这篇文章已经在这里过了六个月,而且没有任何解释。 得出自己的结论。

假设你有


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;

同时使用两个解决方案-> 9232.13

你可以使用DecimalFormat类。


double d = 3.76628729;

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

于 Java Java以前的版本,相关的实 How-to 帖子这里解决方案,这也是 compatible.


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

...