如何避免字符串到双倍转换的指数?
我想我们都错过了这里的重点。
这是您的示例:
// 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
为String
usingString.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
.