Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

-1 left shift by 31

System.out.println((-1<<31));

Why this is giving output -2147483648

I know -1<<31 will give 10000000000000000000000000000000, so it should give ans (int)Math.pow(2,31) that is equals to 2147483648

like image 350
Sukhbir Avatar asked Jul 06 '15 05:07

Sukhbir


3 Answers

-1<<31 gives 10000000000000000000000000000000 which is -2147483648, not 2147483648. Note that the left bit is the sign bit, so if it's 1, this is a negative number.

BTW, 1<<31 would also give you -2147483648, since 2147483648 is higher than Integer.MAX_VALUE. On the other hand, 1L<<31 would give you 2147483648, since the result would be a long.

like image 81
Eran Avatar answered Oct 04 '22 15:10

Eran


I know -1<<31 will give 100000000000000000, so it should give ans (int)Math.pow(2,31) that is equals to 2147483648

That would be the case if int was a two's complement unsigned primitive; but int is signed.

You are correct in the fact that in binary this indeed gives what you say; however, since this is a signed two's complement primitive, the result will be x(0) * 2^0 + x(1) * 2^1 + ... + x(n-2) * 2^(n-2) - x(n-1) * 2^(n-1) (minus, not plus), where x(y) is the value of the y-th bit, counting from 0.

Hence your result.

like image 25
fge Avatar answered Oct 04 '22 15:10

fge


Nowadays in most architectures numbers are stored in 2-complements, see Wikipedia.

So your result is correct. The sign bit is set and all the resting zeros (because 2-complement) makes that the most negative number for that data type, see here.

Thinking in 2-complements

-1 is represented by 1111 1111 1111 1111 1111 1111 1111 1111

31 shifts to the left yields

1000 0000 0000 0000 0000 0000 0000 0000 which represents -2.147.483.648
like image 26
Ely Avatar answered Oct 04 '22 14:10

Ely