我想要的是一种将双精度转换为字符串的方法,该字符串使用半向上舍入方法进行舍入-即,如果要舍入的小数为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中实现这一点的最佳方法是什么?
我来这里只是想得到一个关于如何舍入数字的简单答案。这是提供这一点的补充答案。
如何在Java中舍入数字
最常见的情况是使用Math.rround()。
Math.round(3.7) // 4
数字四舍五入到最接近的整数。A.5值向上舍入。如果需要不同的舍入行为,可以使用其他数学函数之一。请参阅下面的比较。
圆形的
如上所述,这四舍五入到最接近的整数。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
地板
任何十进制值都向下舍入到下一个整数。此方法返回一个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
这与舍入相似,因为十进制值舍入到最接近的整数。然而,与舍入不同,.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 ***
这里有一个更好的函数,它可以正确地舍入像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