Java 从包含大于double.MaxValue的值的字符串分析double

Java 从包含大于double.MaxValue的值的字符串分析double,java,parsing,double,ieee-754,Java,Parsing,Double,Ieee 754,考虑以下java代码: String toParse = "1.7976931348623157E308"; //max value of a double in java double parsed = Double.parseDouble(toParse); System.out.println(parsed); 对于所提到的1.7976931348623157E308值,一切都是有意义的,可以得到正确的输出 现在,如果您试图解析1.7976931348623158E308

考虑以下java代码:

String toParse = "1.7976931348623157E308"; //max value of a double in java        
double parsed = Double.parseDouble(toParse);
System.out.println(parsed);
对于所提到的
1.7976931348623157E308
值,一切都是有意义的,可以得到正确的输出

现在,如果您试图解析
1.7976931348623158E308
(增加
E
之前的最后一位),您仍然会得到打印到控制台中的最大值
仅在尝试解析
1.7976931348623159E308
(最后一个数字再次递增)之后,较大的一个将获得
无穷大

对应负值的行为相同


为什么
。。。8E308
解析为
。。。7E308
而非
无限

parseDouble文档的SE 7版本指的是文档的价值,其中说明:

请注意,四舍五入至最近规则也意味着溢出和下溢行为;如果s的精确值在量级上足够大(大于或等于(MAX_值+ulp(MAX_值)/2),四舍五入到double将导致无穷大;如果s的精确值在量级上足够小(小于或等于MIN_值/2),四舍五入到float将导致零

这与IEEE 754浮点算法中常用的“四舍五入到最近值”规则规定的双精度四舍五入一致

您必须想象转换是通过以下方式完成的:首先计算最近的浮点数,忽略指数限制,然后检查指数是否合适。根据该规则,Double.MAX_值是与严格大于它的某些数字最接近的数字

为确认这是正常舍入行为,请考虑以下程序:

    public class Test {
      public static void main(String[] args) {
        double ulp = Math.ulp(Double.MAX_VALUE);
        System.out.println(ulp);
        System.out.println(Double.MAX_VALUE);
        System.out.println(Double.MAX_VALUE+ulp/2.0000000001);
        System.out.println(Double.MAX_VALUE+ulp/2);
      }
    }
它输出:

1.9958403095347198E292
1.7976931348623157E308
1.7976931348623157E308
Infinity

向Double.MAX_值中添加稍微小于半个ulp的值不会改变它。添加半个ulp会溢出到无穷大。

这与任何应用程序都有关系吗?我猜你对边缘案例很感兴趣。你看过源代码了吗?@AlexWien只是“偶然”发现了这一点,现在我curious@BastiM:将十进制值的二进制表示形式与API中指定的二进制值进行比较。@basti当你看那段代码时,你会失去好奇心,我已经看过了。;-+1对于示例代码,这是让我绞尽脑汁的部分!谢谢,帕特里夏