在 for 循环中使用 Double.POSITIVE_INFINITY (Java)
Using Double.POSITIVE_INFINITY in for loop (Java)
以下代码将如何运行,尤其是当双计数器达到其极限时 ((2-2^-52)·2^1023)?
for (double i = 0; i < Double.POSITIVE_INFINITY; i++){
//do something
}
这段代码会按预期运行(永远循环)还是会在某个时候失败,为什么?
谢谢。
在某些时候,i++
将不再有任何效果,因为对于非常大的 i
值,连续的 double
值相距很远。
因此这是一个无限循环。
要证明有 double
个值 i == i + 1
试试这个:
for (double i = 1;; i *= 2){
if (i == i + 1) {
System.out.println(i);
break;
}
}
它打印
9.007199254740992E15
这段代码永远不会退出循环。
原因是将 1
加到足够大的 double
数上不会改变它的值:
double a = 1.7976931348623155E308;
double old = a;
a++;
System.out.println(a); // prints 1.7976931348623155E308
System.out.println(old); // prints 1.7976931348623155E308
System.out.println(a==old); // prints "true"
事实上,当 double
的值足够接近正无穷大时,您需要添加一个远大于 10200 的数字,以使您的大double 更改值并变为 POSITIVE_INFINITY
.
原因是 double
表示大数的方式。它使用短 mantissa 来表示值的最高有效位,并使用指数来指示小数点应放置的位置。在非常大的数字的情况下,指数本质上是表示在尾数的二进制表示之后需要添加多少个零。
为了让你的double
数字通过加法改变值,你需要添加一个至少与尾数的最低有效位一样大的数字。一旦二进制指数超过 48,为了使结果不同而需要添加的最小数字变为 2,这意味着 ++
将不再更改值。
以下代码将如何运行,尤其是当双计数器达到其极限时 ((2-2^-52)·2^1023)?
for (double i = 0; i < Double.POSITIVE_INFINITY; i++){
//do something
}
这段代码会按预期运行(永远循环)还是会在某个时候失败,为什么?
谢谢。
在某些时候,i++
将不再有任何效果,因为对于非常大的 i
值,连续的 double
值相距很远。
因此这是一个无限循环。
要证明有 double
个值 i == i + 1
试试这个:
for (double i = 1;; i *= 2){
if (i == i + 1) {
System.out.println(i);
break;
}
}
它打印
9.007199254740992E15
这段代码永远不会退出循环。
原因是将 1
加到足够大的 double
数上不会改变它的值:
double a = 1.7976931348623155E308;
double old = a;
a++;
System.out.println(a); // prints 1.7976931348623155E308
System.out.println(old); // prints 1.7976931348623155E308
System.out.println(a==old); // prints "true"
事实上,当 double
的值足够接近正无穷大时,您需要添加一个远大于 10200 的数字,以使您的大double 更改值并变为 POSITIVE_INFINITY
.
原因是 double
表示大数的方式。它使用短 mantissa 来表示值的最高有效位,并使用指数来指示小数点应放置的位置。在非常大的数字的情况下,指数本质上是表示在尾数的二进制表示之后需要添加多少个零。
为了让你的double
数字通过加法改变值,你需要添加一个至少与尾数的最低有效位一样大的数字。一旦二进制指数超过 48,为了使结果不同而需要添加的最小数字变为 2,这意味着 ++
将不再更改值。