Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this multiplication integer overflow result in zero?

After answering this question, I was confused about why the overflowing integer in this code resulted in 0 instead of a negative number. It's strange, why such an exact number? Why 0?

public class IntegerOverflow {
  public static void main(String[] args) {
    int x = 10;

    int i = 0;
    for (i = 0; i <= 5; i++)
    {
      x = x * x;
      System.out.println(x);
    }
  }
}

Output:

100
10000
100000000
1874919424
0
0
like image 250
durron597 Avatar asked Aug 17 '15 03:08

durron597


1 Answers

This will only happen if the starting value of x is even.

According to the JLS §15.17.1:

If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format. As a result, if overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two operand values.

This is made much more obvious if we print the numbers in binary format instead of in decimal:

public class IntegerOverflow {
  public static void main(String[] args) {
    int x = 10;

    int i = 0;
    for (i = 0; i <= 5; i++)
    {
      x *= x;
      System.out.println(Integer.toBinaryString(x));
    }
  }
}

Output:

1100100
10011100010000
101111101011110000100000000
1101111110000010000000000000000
0
0

As you can see, each time we square, we double the number of zero bits. Since only the low order bits are saved, doubling the zeroes every time will eventually result in zero. Notice that we do not see these trailing zeroes if the starting value for x is odd. It will result, instead, it will result in seemingly unrelated numbers like overflow usually does.

public class IntegerOverflow {
  public static void main(String[] args) {
    int x = 11;

    int i = 0;
    for (i = 0; i <= 5; i++)
    {
      x *= x;
      System.out.format("%-12d\t%s%n", x, Integer.toBinaryString(x));
    }
  }
}

Output:

121             1111001
14641           11100100110001
214358881       1100110001101101101101100001
772479681       101110000010110001101011000001
-1419655807     10101011011000011100010110000001
-1709061375     10011010001000011100101100000001
like image 155
durron597 Avatar answered Sep 19 '22 06:09

durron597