0

I am new to bitwise operation. I have the basic concepts of AND, OR, XOR, and 2s complement. However I came across following piece of code and am unable to figure out the output.

char c1 = 0xFF; // -1
int shifted = c1 << 8; //-256 (-1 * 256)
printf("%d, %x\n", shifted, shifted);

int myInt;
myInt = 0xFFFFFFE2;
printf("%d\n", myInt);

int i = 0xff;
printf("%d\n", i<<2);

The output is:

-256, ffffff00
-30
1020

Please help me understand what's going on here!

Sam
  • 86,580
  • 20
  • 181
  • 179
Kunal
  • 511
  • 2
  • 6
  • 12
  • 1
    Read through [this answer](http://stackoverflow.com/a/141873/116286). It's the best bit manipulation overview i've ever read. Although make sure to read the comments at the bottom of the answer, because its written for java and not everything is the same. – jb. Apr 20 '12 at 22:51
  • You've got signed characters on your machine (and 32-bit integers). – Jonathan Leffler Apr 20 '12 at 22:52

3 Answers3

2
char c1 = 0xFF; // -1
int shifted = c1 << 8; //-256 (-1 * 256)

c1 is promoted to int for the shift, so it's still -1, shifting negative ints is implementation-defined, but your implementation seems to do like most and shifts it as if it were an unsigned bit-pattern, so a left-shift by eight places is multiplication by 256.

printf( "%d, %x\n", shifted, shifted );
  -256, ffffff00

as expected. The bit pattern of -256 in two's complement is 0xFFFFFF00 (32-bit ints).

int myInt;
myInt = 0xFFFFFFE2;

That bit pattern is -30 in two's complement

printf("%d\n",myInt);

int i = 0xff ;

This is 255, 255*4 = 1020

printf("%d\n", i<<2);

  -30
  1020
Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
1

Write down c1, myInt and i in binary with the declared number of bits.

Apply the operations to them.

Follow it through.

Martin James
  • 24,453
  • 3
  • 36
  • 60
  • I believe the OP doesn't understand what bit shifting is. so "apply the operations" isn't much help. – jb. Apr 20 '12 at 22:53
  • If the values are writen down in binary, bit-shifting is easily deducted by someone with reasonable English. I accept, of course, that this may be an issue, but I can't help in any languages except English, Spanish and German, (and my German is so bad that I only attempt it outside Germany:). – Martin James Apr 20 '12 at 23:23
1

OK let me explain in some detail what's going on. Any binary notation to clarify will be prefixed with 0b and the most significant bit on the left.

char c1 = 0xFF; // -1

char c1 is an eight-bit signed integer type, which is set to 0b11111111 For signed types such as int, short and char, the leftmost bit is used as the sign bit. In two's complement, the most common standard for storing signed types, any signed integer with all bits set is equal to -1.

int shifted = c1 << 8; //-256 (-1 * 256)

c1 is implicitly cast to a signed integer before the shift, so we have an int of -1 which is 0xffffffff. The shift operator in C is a non-rotating shift, i.e. any bits shifted "from" outside the value will be set to zero. After the shift we have 0xffffff00, which is equal to -256 in two's complement.

printf( "%d, %x\n", shifted, shifted );

int myInt;
myInt = 0xFFFFFFE2;
printf("%d\n",myInt);

You're reading a signed integer which is printed according to two's complement.

int i = 0xff ;
printf("%d\n", i<<2);

The initial i is equivalent to 0b11111111, the sign bit not being set. After the shift we have 0b1111111100, which is equal to 1020, again because of non-rotating shift. Hope that clarifies things a bit. If you want to do bit shifts and AND/OR logic you should typically use unsigned types as mentioned before.

smocking
  • 3,689
  • 18
  • 22