繁体   English   中英

从包含大于Double.MaxValue的值的字符串解析double

[英]Parsing a double from a string which holds a value greater than Double.MaxValue

考虑以下java代码:

String toParse = "1.7976931348623157E308"; //max value of a double in java        
double parsed = Double.parseDouble(toParse);
System.out.println(parsed);

对于上面提到的值1.7976931348623157E308一切都有意义,一个得到正确的输出。

现在,如果有人试图解析1.7976931348623158E308E递增之前的最后一位数字),您仍然可以获得打印到控制台的最大值!
只有在尝试解析1.7976931348623159E308 (再次最后一位数增加)后,才能获得Infinity
相应负值的行为相同。

为什么... 8E308解析为... 7E308而不是Infinity

serseDouble文档的SE 7版本引用了valueOf文档,其中说:

请注意,舍入到最近的规则也意味着溢出和下溢行为; 如果s的精确值在幅度上足够大(大于或等于(MAX_VALUE + ulp(MAX_VALUE)/ 2),则舍入为double将导致无穷大,并且如果s的精确值在幅度上足够小(更少)等于或等于MIN_VALUE / 2),舍入到浮点将导致零。

这与对double类型的舍入是通过IEEE 754浮点运算的通常舍入到最接近的规则的说法是一致的。

您必须通过首先计算忽略指数限制的最近浮点数,然后检查指数是否适合来设想转换。 Double.MAX_VALUE是该规则下最接近某些严格大于它的数字的数字。

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

    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_VALUE添加甚至略低于半个ulp的东西不会改变它。 添加半个ulp溢出到无穷大。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM