java - 这是根据规范进行的 Java 双重解析行为吗?

标签 java parsing double number-formatting

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/

相关文章:

java - Spring MVC 基于 Java 的配置看不到类路径属性文件

java - 计算字符串中的字母 Java

java - 从 int 创建时钟格式

java - 使用 BigDecimals 计算 p 的 n 次方根

java - 与直接使用 System.currentTimeMillis() 相比,使用 CountDownTimer() 有何优势

PHP 不再处理 html

c++ - 将多种类型分配给 Bison 中的非终端

java - 在数组中存储坐标并在java中比较它们的最佳方法?

android - 不能在原始 double 上调用 toString()

swift - swift 乘以变量和 double