I am not able to understand the output of below code . It gives me output as -256.
char c = 0xFF;
printf("%d\n",c<<8);
I am not able to understand the output of below code . It gives me output as -256.
char c = 0xFF;
printf("%d\n",c<<8);
First of all, in your platform char
is a signed type, which goes from -128
to 127
. Following the 2's complement representation
, positive numbers are represented from 0x00
to 0x7f
and from there, the negative numbers start. So 0x80
is -128, 0x81
is -127
, and so on, until arriving to 0xFF
which is -1
.
In your code, you are assigning -1
to the variable c
. When you bitshift a char
, it gets promoted to int
, so you end up with the representation of -1
in integer, which is (just to give an example) 0xFFFFFFFF
if int
was 32 bits.
When you bitshift a negative number to the left, the least significant bits get filled by 0's, so you end up having 0xFFFFFF00
which is -256
.
Computers represent negative numbers by using Two's Complement. When you declare a char
, you allocate a byte which is 8 bits. If the variable is signed and its most significant bit is 1, it will be the negative value of the 2^n
place.
For example, a char
which has 8 bits and its sigbit is 1, 0x80 = 1000 0000 = -2^8 = -128
. When you set the remaining bits to 1, you add back the positive values of each 2^n
bit place. See more about binary representation of numbers here. Each hexadecimal character represent four bits, in the case of 0xFF
, you set c
's eight bits to 1s.
char c = 0xFF; // 0xFF = 1111 1111 = -1
So you have -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1
When you preform a left-shift c << x
, you move c
's bits to the left x
amount while padding the right with zeros as you shift. Here is a explanation from a previous stackoverflow answer by @legends2k.
The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1×2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and non-negative value, and E1×2E2 is representable in the result type, then that is the resulting value; otherwise, the behaviour is undefined. reference
In addition, when you preform a shift, you promote c
to an int
.
ISO/IEC 9899:2011 (C)
§6.5.7 Bitwise shift operators
1183 The integer promotions are performed on each of the operands.
To preserve the value of -1 being 0xFF
in the sense of a char
, on a 32-bit machine, an integer is 4 bytes with its bits all being 1s to represent -1 or 0xFFFFFFFF
.
When you shift 8 bits to the left, (0xFFFFFFFF << 8) = 0xFFFFFF00 = -256