loubas
loubas

Reputation: 191

bitwise operations in c explanation

I have the following code in c:

 unsigned int a = 60; /* 60 = 0011 1100 */
 int c = 0;
 c = ~a; /*-61 = 1100 0011 */
 printf("c = ~a = %d\n", c );
 c = a << 2; /* 240 = 1111 0000 */
 printf("c = a << 2 = %d\n", c );

The first output is -61 while the second one is 240. Why the first printf computes the two's complement of 1100 0011 while the second one just converts 1111 0000 to its decimal equivalent?

Upvotes: 0

Views: 241

Answers (2)

paddy
paddy

Reputation: 63451

You have assumed that an int is only 8 bits wide. This is probably not the case on your system, which is likely to use 16 or 32 bits for int.

In the first example, all the bits are inverted. This is actually a straight inversion, not two's complement:

1111 1111 1111 1111 1111 1111 1100 0011  (32-bit)
                    1111 1111 1100 0011  (16-bit)

In the second example, when you shift it left by 2, the highest-order bit is still zero. You have misled yourself by depicting the numbers as 8 bits in your comments.

0000 0000 0000 0000 0000 0000 1111 0000  (32-bit)
                    0000 0000 1111 0000  (16-bit)

Upvotes: 6

TypeIA
TypeIA

Reputation: 17250

Try to avoid doing bitwise operations with signed integers -- often it'll lead you into undefined behavior.

The situation here is that you're taking unsigned values and assigning them to a signed variable. For ~60 this is undefined behavior. You see it as -61 because the bit pattern ~60 is also the two's-complement representation of -61. On the other hand 60 << 2 comes out correct because 240 has the same representation both as a signed and unsigned integer.

Upvotes: 0

Related Questions