Here is my code
int a=2147483647;
int b= a<<1;
cout<<"a="<<a<<", b="<<b;
The output I am getting is- a=214783647, b=-2
Binary representation of a is
0111 1111 1111 1111 1111 1111 1111 1111
By shifting it by 1 bit, it will change sign bit and replace LSB with 0. So, I think answer will be -ve and magnitude will be subtracted by 1 ie -2147483646 But it is giving result as -2 . Please explain.
[expr.shift]/1 The value of
E1 << E2
isE1
left-shiftedE2
bit positions; vacated bits are zero-filled. ... ifE1
has a signed type and non-negative value, andE1 × 2^E2
is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined .
Emphasis mine. Your program exhibits undefined behavior.
Edit: Upon closer consideration, I no longer think it's undefined behavior. 2147483647*2
does fit into unsigned int
, "the corresponding unsigned type" of int
. Its conversion to int
is not undefined, but merely implementation-defined. It's entirely reasonable for an implementation using two's complement to define this conversion so that 2147483647*2 == -2
, just reinterpreting the bit pattern, as other answers explained.
This is because your computer is using 2 complement for the signed value. Unsigned shifted value is 0xFFFFFFFE
, which is -2 in 2 complement, not -2147483647
.
Shifting is implementation defined in C.
BTW, -2147483647
is 0x80000001
on such CPU.
Well, there is a very long story behind.
Since int is a signed type, it means that the first bit is a sign and the whole system is two-complement.
so x = 0b 1111 1111 1111 1111 1111 1111 1111 0111 is x = -9 and for example x = 0b 1111 1111 1111 1111 1111 1111 1111 1111 is x = -1 and x = 0b 0000 0000 0000 0000 0000 0000 0000 0010 is 2
Learn more about Two complement .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.