Why does i = i + i give me 0?

DeaIss picture DeaIss · Jun 12, 2014 · Viewed 22.4k times · Source

I have a simple program:

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

When I run this program, all I see is 0 for i in my output. I would have expected the first time round we would have i = 1 + 1, followed by i = 2 + 2, followed by i = 4 + 4 etc.

Is this due to the fact that as soon as we try to re-declare i on the left hand-side, its value gets reset to 0?

If anyone can point me into the finer details of this that would be great.

Change the int to long and it seems to be printing numbers as expected. I'm surprised at how fast it hits the max 32-bit value!

Answer

Ali Gajani picture Ali Gajani · Jun 12, 2014

Introduction

The problem is integer overflow. If it overflows, it goes back to the minimum value and continues from there. If it underflows, it goes back to the maximum value and continues from there. The image below is of an Odometer. I use this to explain overflows. It's a mechanical overflow but a good example still.

In an Odometer, the max digit = 9, so going beyond the maximum means 9 + 1, which carries over and gives a 0 ; However there is no higher digit to change to a 1, so the counter resets to zero. You get the idea - "integer overflows" come to mind now.

enter image description here enter image description here

The largest decimal literal of type int is 2147483647 (231-1). All decimal literals from 0 to 2147483647 may appear anywhere an int literal may appear, but the literal 2147483648 may appear only as the operand of the unary negation operator -.

If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format. If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values.

Thus, 2147483647 + 1 overflows and wraps around to -2147483648. Hence int i=2147483647 + 1 would be overflowed, which isn't equal to 2147483648. Also, you say "it always prints 0". It does not, because http://ideone.com/WHrQIW. Below, these 8 numbers show the point at which it pivots and overflows. It then starts to print 0s. Also, don't be surprised how fast it calculates, the machines of today are rapid.

268435456
536870912
1073741824
-2147483648
0
0
0
0

Why integer overflow "wraps around"

Original PDF