考虑下面的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
(最后一位数字再次增加)并且更大的一位得到Infinity
.
相应负值的行为相同。
Why is ... 8E308
解析为... 7E308
并不是Infinity
?
SE 7 版本的 parseDouble 文档引用了 valueOf 文档,其中表示:
请注意,舍入到最接近的规则还意味着溢出和下溢行为;如果 s 的精确值的大小足够大(大于或等于 (MAX_VALUE + ulp(MAX_VALUE)/2),则四舍五入到双倍将导致无穷大,并且如果 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 会溢出到无穷大。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)