在Java ME中将double舍入到5位小数

12

如何将一个double类型的数字四舍五入保留5位小数,且不使用DecimalFormat?


1
你为什么要避免已经存在的这个类呢?如果你想要结果是一个double类型,那么你基本上是在要求一些不可能的事情。除了一些特殊情况外,你根本无法将一个二进制double类型四舍五入到指定数量的十进制位数。 - Michael Borgwardt
5
@ Michael:JavaME中没有DecimalFormat。 - Kevin Boyd
8个回答

15

你可以通过将第五个小数位作为第一位来将数字四舍五入到第五个小数位。然后进行普通的四舍五入,并再次将结果调整为第五个小数位。

假设需要四舍五入的值是一个名为xdouble类型的变量:

double factor = 1e5; // = 1 * 10^5 = 100000.
double result = Math.round(x * factor) / factor;
如果您想保留6位小数,让factor等于1e6,以此类推。

3
无法相信这个回答会得到这么多的投票,因为这并不是真正的四舍五入。请参考Jon的回答了解原因。 - Michael Borgwardt
我看不出问题所在。问题是如何将double舍入到五位小数,这已经是最好的解决方案了。显然,如果您要表示十进制值,就不应该实际使用double,但这不是问题的关键。 - Joren
1
注意:虽然它可能将数字限制为5位数,但无法确定其是否正确,因为它无法确保整数值Math.round(x * factor)可以表示为factor分之一,或者它将被限制在指数值的位置(即小数部分的5个位置)。有关更多信息,请参见Java理论与实践:你的点在哪里?(舍入误差)每个科学家都应该了解的浮点算术知识 - mctylr
@mctylr:你说得对,当然正确性是很重要的,但正如我之前所说,这是使用“double”得到的最佳方式。如果您想要精确的十进制计算,就不应该使用“double”。二进制浮点计算用于诸如科学计算之类的事情,其中所有值都本质上是不精确的,在这种情况下,例如为了显示目的而进行一些近似的四舍五入到5个小数位是完全可以接受的 - Joren
4
J2ME 中没有 Math.round() 方法。 - Nate

11

无论你做什么,如果最终得到的是 double 值,它不太可能是精确到 5 位小数。这不是二进制浮点算术工作的方式。最好的情况是“离原始值 最接近 的 double 值,四舍五入到 5 位小数”。如果你打印出该 double 值的 精确 值,它仍然可能有超过 5 位小数。

如果你真的需要精确的十进制值,应该使用 BigDecimal


5
无论做什么,你都不能在Java ME中使用BigDecimal,因为这种类型在CLDC和CDC配置文件中都不存在。 - gnat

8

将数值乘以100000,再加上0.5,然后取整。最后将结果除以100000。

代码:

double original = 17.77777777;
int factor = 100000;
int scaled_and_rounded = (int)(original * factor + 0.5);
double rounded = (double)scaled_and_rounded / factor;

3

2
DecimalFormat roundFormatter = new DecimalFormat("########0.00000");

public Double round(Double d)
    {
        return Double.parseDouble(roundFormatter.format(d));
    }

2
尝试以下操作:
double value = Double.valueOf(String.format(Locale.US, "%1$.5f", 5.565858845));

System.out.println(value); // prints 5.56586

value = Double.valueOf(String.format(Locale.US, "%1$.5f", 5.56585258));

System.out.println(value); // prints 5.56585

如果您希望代码量最小化,可以使用"import static"。
import static java.lang.Double.valueOf;
import static java.util.Locale.US;
import static java.lang.String.format;

并且

double value = valueOf(format(US, "%1$.5f", 5.56585258));

敬礼,


1
public static double roundNumber(double num, int dec) {
        return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
}

0

我在这里偶然发现了一个方法,可以将我的双精度数字限制为两位小数,不截断也不四舍五入。Math.Truncate 可以给出双精度数的整数部分,并丢弃小数点后的所有内容,因此 10.123456 在截断后变成了 10。Math.Round 将数字四舍五入到最接近的整数值,因此 10.65 变成了 11,而 10.45 变成了 10。因此,这两个函数都不能满足我的需求(希望 .Net 可以重载这两个函数,允许将数字截断或四舍五入到一定数量的小数位)。我需要的最简单的方法是:

//First create a random number 
Random rand = new Random();

//Then make it a double by getting the NextDouble (this gives you a value 
//between 0 and 1 so I add 10 to make it a number between 10 and 11
double chn = 10 + rand.NextDouble();

//Now convert this number to string fixed to two decimal places by using the
//Format "F2" in ToString
string strChannel = chn.ToString("F2");

//See the string in Output window
System.Diagnostics.Debug.WriteLine("Channel Added: " + strChannel);

//Now convert the string back to double so you have the double (chn) 
//restricted to two decimal places
chn = double.Parse(strChannel);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接