0

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 ?

1
  • ~0 << 5 causes undefined behaviour (left shift of negative value). Using %u with a negative value also causes undefined behaviour. Commented Jul 15, 2015 at 5:02

4 Answers 4

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
Sign up to request clarification or add additional context in comments.

Comments

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 

Comments

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).

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.