如何避免字符串到双倍转换的指数?
我想我们都错过了这里的重点。
这是您的示例:
// value = "987654321.45"
double amount1 = Double.parseDouble(value);
// amount1 = 9.8765432145E8
大概是评论里的东西被打印出来了;例如使用调试器或调用println.
那么为什么你会看到指数/科学记数法呢?
好吧,这不是由于将字符串解析为double. 它实际上是在将double其转换回字符串以打印它时发生的。例子:
$ cat Test.java
import java.text.DecimalFormat;
public class Test {
public static void main(String[] args) {
String value = "987654321.45";
double amount = Double.parseDouble(value);
System.out.println(amount);
DecimalFormat format = new DecimalFormat("0.########");
System.out.println(format.format(amount));
}
}
$ java Test
9.8765432145E8
987654321.45
看?我从“987654321.45”开始,将其转换为double. 然后用两种不同的方式打印出来。并为相同的值获得了两种不同的字符串表示double
那么为什么要这样println(double)打印数字呢?
出色地 ...
System.out是一个PrintStream
println(double)相当于print(double)后面跟着println()
print(double)将 the 转换double为StringusingString.valueOf(double)
valueOf(double)返回与Double.toString(double)
toString(double)如果数字的大小小于 10 -3或大于或等于 10 7,则指定使用科学计数法。
这都在各自的 javadocs 中指定。最突出的是用于toString(double).
如果你不相信我,你可以查看 Java 语言规范和浮点表示的 IEE 754 标准;见维基百科。
如果你愿意,你甚至可以用它来检查一个值Double.doubleToRawLongBits(double)的位表示。double
最后
经过计算,我得到了4.3827160725E14不正确的正确答案是493827.16。
当我重复该计算时,我得到了答案493827.1607250001……使用System.out.println(double). (注意没有科学记数法……因为数字小于 10 7。)
计算的确切答案 (1987654321.45 * 0.05) / 100 493827.160725。确切答案与 Java 给出的答案之间的差异是由计算机浮点舍入误差引起的。发生这种情况是因为 IEE 754 表示实际上是具有二进制尾数和二进制指数的二进制表示,并且因为尾数具有固定数量的二进制精度位数。
这种舍入误差是使用 IEE 754 表示的计算所固有的。如果你想减轻它,你可以用BigDecimal来表示你的数字。但是您应该知道,即使BigDecimal是不精确的:
因此,您仍然(理论上)需要关注BigDecimal.