0

I have the following method:

int x= (int) Math.pow(2, 5);
for (int k=1; k <= 3; k++) {
    x *= (2*x);
}
System.out.println(x); // prints 0

It is simply initializing x to 32 and then multiplying it by its double every iteration of the loop. However, I expect the output the be a big number or at least an error, but the final output is 0. No, I tried to do some debugging by adding this:

int x= (int) Math.pow(2, 5);
for (int k=1; k <= 3; k++) {
    System.out.println(x + " * " + 2 * x);
    x *= (2*x);
}
System.out.println(x);

But the output is this:

32 * 64
2048 * 4096
8388608 * 16777216
0

Does anyone have any idea why the number suddenly becomes 0?

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
Pablo
  • 1,302
  • 1
  • 16
  • 35
  • try debugging by printing `System.out.println(Integer.toBinaryString(x).length());` and you see that the next in the series is `32` – Scary Wombat May 01 '18 at 01:25
  • You have an overflow that causes the result of the multiplication operation to give a wrong value. As `Integer` are coded on 32bits in Java the maximum value that can be assigned to a `int` variable before reaching an overflow is defined by `Integer.MAX_VALUE;//2147483647`. As work-around you can use `BigInteger` to do calculation over this limit (see Tim solution) If you want to understand why the result is `0` and not `-1234578` or another number have a look at this link: https://stackoverflow.com/questions/32042346/why-does-this-multiplication-integer-overflow-result-in-zero – Allan May 01 '18 at 01:34
  • The numbers are too large, you need to use the BigInteger java import. This should help introduce you to how to use the import: https://www.geeksforgeeks.org/biginteger-class-in-java/ – Alex Reed May 01 '18 at 01:23

2 Answers2

1

32 in binary is 100000, a power of 2. Your "update procedure" x = 2 * x * x; maintains this property -- x is always a (bigger) power of 2. At the last iteration, you're seeing x overflow, since the int datatype only stores 32 bits, and the binary representation of x has more than 32 bits. The value printed is exactly 0 because the lowest 32 bits of x are all 0 (since x is a very large power of 2), and the int with 32 0's is 0.

k_ssb
  • 6,024
  • 23
  • 47
  • So when I reach a value greater than 32 bits, Java automatically defaults to a 32 bit integer made of 0's? – Pablo May 01 '18 at 12:50
  • When you need more than 32 bits to store an integer, Java's `int` type stores the "lowest" (least-significant) 32 bits. In your case, all of the lowest 32 bits happen to be `0`'s because your number is a large power of 2. – k_ssb May 01 '18 at 21:00
0

You are just looking at standard primitive integer overflow, which have a max value of 2,147,483,647. Java has a class BigInteger which has a much larger range (no theoretical limit) which you may use:

BigInteger x= new BigInteger(String.valueOf((int)Math.pow(2, 5)));
for (int k=1; k <= 3; k++) {
    System.out.println(x + " * " + x.multiply(new BigInteger("2")));
    BigInteger twice = x.multiply(new BigInteger("2"));
    x = x.multiply(twice);
}
System.out.println(x);

32 * 64
2048 * 4096
8388608 * 16777216
140737488355328

Demo

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • To the downvoter: I answered substantially before the question was marked duplicate. It is bizarre that you would downvote this answer while leaving the OP alone. – Tim Biegeleisen May 01 '18 at 01:56