我遇到了一个非常奇怪的问题。我从同一个操作得到两个不同的输出。问题在这里描述。
double num = 2.0170818E7;
int dp = 4;
String s = (Math.round(num * Math.pow(10, dp)) / (int) Math.pow(10, dp)) + "";
当我在Android 5.0+中运行上面的代码集时,我得到的输出为:
正确输出:
20170818
当我在Android 5.0下面运行上面的代码集时(我尝试使用4.4.2版本),我得到输出为:
输出错误:
20172835
正确的输出是20170818
或预期的输出。为什么我会遇到这个奇怪的问题?
答案 0 :(得分:7)
最初Android开发工具仅支持jdk 6功能。但是在2013年10月首先由Android Studio 0.3.2更改了。如果您的目标是Android 5.0及更高版本,则需要.Java 7或更高版本。现在可以使用java 8的一些功能。
JDK 8对问题JDK-7131459: DecimalFormat produces wrong format() results when close to a tie中的DecimalFormat
四舍五入进行了故意更改。
但是,这些更改引入了一个真正的错误,其归档为JDK-8039915: Wrong NumberFormat.format() HALF_UP rounding when last digit exactly at rounding position greater than 5。例如:
99.9989 -> 100.00
99.9990 -> 99.99
答案 1 :(得分:2)
BigDecimal实现:
double num = 2.0170818E7;
int dp = 4;
BigDecimal pow = new BigDecimal(Math.pow(10, dp));
BigDecimal bigDecimal = new BigDecimal(num);
BigDecimal result = bigDecimal.multiply(pow);
result = result.divide(pow);
String s = result.toString();
答案 2 :(得分:0)
[我没有准备好Android环境,因此无法自行检查...]
检查Math.pow(10,dp)
的值。它可能是不精确的(可能是9999.999999左右,查看结果数字。将其转换为int给出9999而不是10000。
将其替换为足够大小的static final int[] POWERS = {1, 10, 100, 1000, 10000 ... }
数组,并使用POWERS[dp]
代替Math.pow(10,dp)
计算。那你就有了确切的价值。
或者至少直接除以Math.pow()表达式,而不是它的int-cast,截断值。
答案 3 :(得分:0)
你得到这种“奇怪”的行为,因为你在Java中做浮点算术。除非你用完整数范围,否则只有整数的算术是准确的。另一方面,浮点运算并不精确,因为一些实数需要表示无限数量的数字。在Java中,当您开始使用“double”或“float”进行实际计算时(其值超出int范围),您的程序将变得不确定。从您的一条评论中我了解到您是一名物理学家,因此您可能对确定性计算感兴趣,如果是这样,您可能需要考虑使用strictfp库(Java有一个strictfp选项,我不知道Android)