我想要的是一种将双精度转换为字符串的方法,该字符串使用半向上舍入方法进行舍入-即,如果要舍入的小数为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中实现这一点的最佳方法是什么?
当尝试舍入到小数位数的负数时,Math.round解决方案存在问题。考虑代码
long l = 10;
for(int dp = -1; dp > -10; --dp) {
double mul = Math.pow(10,dp);
double res = Math.round(l * mul) / mul;
System.out.println(""+l+" rounded to "+dp+" dp = "+res);
l *=10;
}
这是结果
10 rounded to -1 dp = 10.0
100 rounded to -2 dp = 100.0
1000 rounded to -3 dp = 1000.0
10000 rounded to -4 dp = 10000.0
100000 rounded to -5 dp = 99999.99999999999
1000000 rounded to -6 dp = 1000000.0
10000000 rounded to -7 dp = 1.0E7
100000000 rounded to -8 dp = 1.0E8
1000000000 rounded to -9 dp = 9.999999999999999E8
当1除以1.0E-5时会出现小数位数为-5的问题,这是不精确的。
可以使用
double mul = Math.pow(10,dp);
double res;
if(dp < 0 ) {
double div = Math.pow(10,-dp);
res = Math.round(l * mul) *div;
} else {
res = Math.round(l * mul) / mul;
}
但这是使用BigDecimal方法的另一个原因。