为什么 i = i + i 给我 0?

2022-08-31 10:39:58

我有一个简单的程序:

public class Mathz {
    static int i = 1;
    public static void main(String[] args) {    
        while (true){
            i = i + i;
            System.out.println(i);
        }
    }
}

当我运行这个程序时,我看到的只是在我的输出中。我本来以为我们会有的第一轮,然后是,然后是等等。0ii = 1 + 1i = 2 + 2i = 4 + 4

这是因为一旦我们尝试在左侧重新声明,其值就会重置为 ?i0

如果有人能向我指出这个细节的细节,那就太好了。

将 更改为,它似乎正在按预期打印数字。我对它达到最大32位值的速度感到惊讶!intlong


答案 1

介绍

问题是整数溢出。如果它溢出,它将返回到最小值并从那里继续。如果它下溢,它将返回到最大值并从那里继续。下图是里程表。我用它来解释溢出。这是一个机械溢出,但仍然是一个很好的例子。

在里程表中,,超出最大均值,它延续并给出一个;但是,没有更高的数字可以更改为 a,因此计数器重置为 。你明白了 - “整数溢出”现在浮现在脑海中。max digit = 99 + 101zero

enter image description hereenter image description here

int 类型的最大十进制文本是 2147483647 (231-1)。从 0 到 2147483647 的所有十进制文本都可能出现在 int 文本可能出现的任何位置,但文本2147483648可能仅作为一元否定运算符 -的操作数出现。

如果整数加法溢出,则结果是数学和的低阶位,以某种足够大的二进制补码格式表示。如果发生溢出,则结果的符号与两个操作数值的数学和的符号不同。

因此,溢出并环绕到 。因此会溢出,这不等于 。另外,你说“它总是打印0”。它没有,因为 http://ideone.com/WHrQIW。下面,这 8 个数字显示了它枢轴和溢出的点。然后它开始打印0s。另外,不要惊讶它的计算速度有多快,今天的机器速度很快。2147483647 + 1-2147483648int i=2147483647 + 12147483648

268435456
536870912
1073741824
-2147483648
0
0
0
0

为什么整数溢出“环绕”

原始 PDF 格式


答案 2

此问题是由于整数溢出。

在 32 位二进制补码算术中:

i确实开始时具有 2 的幂值,但是一旦达到 230,溢出行为就开始了:

230 + 230 = -231

-231 + -231 = 0

...在算术中,因为它本质上是算术mod 2 ^ 32。int