1

I don't understand the output of this code:

main() {
    int ret = ~(~0 <<5) << 2;
    printf("ret: %d, %u\n", ret, ret);
}


output:
ret: 124, 124

If I process mentally, I do this:

  • resolving ~0 gives binary 1
  • resolving ~0 << 5 gives binary 100000
  • resolving ~(~0 << 5) gives binary 011111
  • resolving ~(~0 << 5) << 2 gives binary 111100
  • convert binary 111100 to decimal gives 60

What did I do wrong ?

ling
  • 9,545
  • 4
  • 52
  • 49
  • `~0 << 5` causes [undefined behaviour](http://stackoverflow.com/a/4105123/1505939) (left shift of negative value). Using `%u` with a negative value also causes undefined behaviour. – M.M Jul 15 '15 at 05:02

4 Answers4

6

Integral literals in C are ints by default, and int is usually 4 bytes long (depending on the compiler). This means that ~0 is not 1, it's 32 1s.

~0 == 11111111111111111111111111111111
~0 << 5 == 11111111111111111111111111100000
~(~0 << 5) == 00000000000000000000000000011111
~(~0 << 5) << 2 == 00000000000000000000000001111100
Miles Budnek
  • 28,216
  • 2
  • 35
  • 52
1

resolving ~0 gives binary 1

That is incorrect.

0 is represented by all zero bits. ~0 turns all bits into 1. On a 32 bit system,

0 == 00000000 00000000 00000000 00000000
~0 == 11111111 11111111 11111111 11111111 
R Sahu
  • 204,454
  • 14
  • 159
  • 270
1
if int is 4 bytes then:
~0        = 11111111111111111111111111111111 = -1        
-1 << 5   = 11111111111111111111111111100000 = -32        
~-32      = 00000000000000000000000000011111 =  31          
31 << 2   = 11111111111111111111111000000000 = 124        

if int is 2 bytes then:
~0        = 1111111111111111                 = 65535
65535 << 5= 1111111111100000                 = 65504
~65504    = 0000000000011111                 = 31
31 << 2   = 0000000001111100                 = 124


int is guaranteed to be able to hold -32767 to 32767,
which requires 16 bits.
In that case, int , is 2 bytes.
However, implementations are free to go beyond that minimum,
as you will see that many modern compilers make int 32-bit 
(which also means 4 bytes pretty ubiquitously).
Jon Goodwin
  • 9,053
  • 5
  • 35
  • 54
0

~0 is all 1's in binary.

The left shift by 5 is going to have 5 0's and then all 1's.

~ This is 5 1's; this is 31.

left shift by 2 bits is equal to multiplying by 4, leaving you 124 as the final answer.

Caleb An
  • 366
  • 1
  • 10