在 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"

Demo.

事实上,当 double 的值足够接近正无穷大时,您需要添加一个远大于 10200 的数字,以使您的大double 更改值并变为 POSITIVE_INFINITY.

原因是 double 表示大数的方式。它使用短 mantissa 来表示值的最高有效位,并使用指数来指示小数点应放置的位置。在非常大的数字的情况下,指数本质上是表示在尾数的二进制表示之后需要添加多少个零。

为了让你的double数字通过加法改变值,你需要添加一个至少与尾数的最低有效位一样大的数字。一旦二进制指数超过 48,为了使结果不同而需要添加的最小数字变为 2,这意味着 ++ 将不再更改值。