java.lang.Double.parseValue
方法以不一致的方式处理奇怪的 double 表示。
如果你写了一个非常大的数字,大到超出 double
的范围,但随后附加一个大的负指数以使其回到范围内,你最终会在范围内 (此处在 Scala 的 REPL 中进行了说明):
scala>
java.lang.Double.parseDouble("10000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000001e-400")
res25: Double = 1.0E-21
另一方面,如果你写了一个非常小的数字,小到超出 double
的范围,然后使用一个大的正指数将它带回范围内,它仅当指数本身不太大时才有效:
scala>
java.lang.Double.parseDouble("0.000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000001e400")
res26: Double = Infinity
scala>
java.lang.Double.parseDouble("0.000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000001e200")
res27: Double = 1.0E-179
这仅仅是一个错误,还是某个地方的规范允许这种行为,或者规范允许所有这些都失败,当一个人得到正确的结果时应该感谢自己的祝福? (如果是bug,修复了吗?)
(顺便说一句:我正在编写自定义 String-to-double 代码,并打算在棘手的情况下推迟到 Java 默认实现,但这个测试用例失败了。)
最佳答案
我认为这是一个边缘案例,但也是一个错误。一个更简单的例子是
String text = "0.000000000000000001e326";
System.out.println(Double.parseDouble(text));
System.out.println(new BigDecimal(text).doubleValue());
在 Java 7 update 25 和 Java 8 update 5 中打印
Infinity
1.0E308
BigDecimal 解析并转换为 double 表明这个数字是可表示的。
关于java - 这是根据规范进行的 Java 双重解析行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23723763/