Understanding Bitwise Operators and Literals

So here are the lines of code I need help understanding:

1
2
  unsigned s = 555;
  int i = (s >> 4) & ~(~0 << 3);


I think I understand most of this, but I'm not sure I understand why ~0 = -1.

How exactly is the literal 0 being stored? I initially assumed that 0 would be treated as a signed int and stored as 000...00000 with the left-most bit being the sign bit, but if that were the case then ~0 would have to be 111...11111, or -2^16, right?

So it seems that it must be stored as only 2 bits, 00, with the left-most bit being the sign bit, and ~0 being stored as 11, or -1, and then the computer allocates more space in the registers or something as it uses the left shift bitwise operator, to get 11000, or -8. This seems wrong to me, but it's the only way I've been able to make sense of this...

Anyway, tell me why I'm wrong.
It would be more correctly to write

unsigned s = 555;
int i = (s >> 4) & ~(~0u << 3);

0u is unsigned int. ~0u produces all ones, that is 11111111 11111111 11111111 11111111 if sizeof( unsigned int ) == 4.
~0u << 3 produces

11111111 11111111 11111111 11111000

~( ~0u << 3 )

will invert bits

00000000 00000000 00000000 00000111.

So the aim of the expression

(s >> 4) & ~(~0u << 3)

is to get the last three bits (the less significant) of s >> 4.
That definitely makes sense, but I still don't understand how the 0 is being treated if not cast as an unsigned int.

Basically, I don't understand why
1
2
 std::cout << ~0;
 std::cout << (~0 << 3);

yields -1 and -8.



0 is a integer literal of type int. So then you use ~0 you get

11111111 11111111 11111111 11111111

that is equal to -1 because it is a value of type int and the sign bit is set. After ~0 << 3 you get

11111111 11111111 11111111 11111000

Again it is a negative value because its sign bit is set. It is equal to -8. If you will add 8 that is represented as

00000000 00000000 00000000 00001000

you will get

11111111 11111111 11111111 11111000
+
00000000 00000000 00000000 00001000
==========================
00000000 00000000 00000000 00000000

that is as you see the result will be equal to zero.
ah ok I wasn't understanding how negative integers were represented.

Thanks.
Topic archived. No new replies allowed.