hanish
hanish

Reputation: 123

Precedence while using right and left shift operators

I want to know how the output of following C program is 32. Please provide me a step by step guidance on the same.

main()
{
    int a=4,b=2;
    a=b<<a+b>>2;
    printf("%d",a);
}

Upvotes: 3

Views: 130

Answers (3)

user2371524
user2371524

Reputation:

Asking about precedence, + has higher precedence than << and >>, so the expression is

b << (a + b) >> 2

evaluated as

2 << (4 + 2) >> 2 = 2 << 6 >> 2

Now, there's again to decide which part is evaluated first -- << and >> have the same precedence, but associativity comes to the rescue, for << and >> it is left-to-right, so this means the leftmost operator is evaluated first:

(2 << 6) >> 2 = 128 >> 2 = 32

edit: doing all in one step, respecting precedence and associativity, your original expression b<<a+b>>2 reads the following fully parenthesized:

((b << (a + b)) >> 2

For future doubts, it's very helpful to have a table showing both precedence and associativity. Or just use some "superfluous" parenthesis to make the expression more readable to humans ;)

Upvotes: 5

Tamir Vered
Tamir Vered

Reputation: 10287

If you look at the disassembly of this code:

    31:                 int a = 4, b = 2;
00007FFE91FC449C C7 45 24 04 00 00 00 mov         dword ptr [rbp+24h],4  
00007FFE91FC44A3 C7 45 20 02 00 00 00 mov         dword ptr [rbp+20h],2  
    32:                 a = b << a + b >> 2;
00007FFE91FC44AA 8B 4D 24             mov         ecx,dword ptr [rbp+24h]  
00007FFE91FC44AD 8B 45 20             mov         eax,dword ptr [rbp+20h]  
00007FFE91FC44B0 03 C8                add         ecx,eax  
00007FFE91FC44B2 83 E1 1F             and         ecx,1Fh  
00007FFE91FC44B5 8B 45 20             mov         eax,dword ptr [rbp+20h]  
00007FFE91FC44B8 D3 E0                shl         eax,cl  
00007FFE91FC44BA 8B C8                mov         ecx,eax  
00007FFE91FC44BC C1 F9 02             sar         ecx,2  
00007FFE91FC44BF 89 4D 24             mov         dword ptr [rbp+24h],ecx 

As you can see, the + operator is done first, and the << and >> operators have the same precedence and have left to right associativity (and therefore executed from left to right) so your code can be simplified to:

main()
{
    int a = 4, b = 2;
    a = a + b; //6
    a = b << a; //128
    a = a >> 2; //32
    printf("%d", a);
}

Note that there are no actual assignments to a in the function other than the last assignment and the decleration.

And your code is the same as if you would write it as a = b << (a + b) >> 2;.

Upvotes: 0

Himanshu
Himanshu

Reputation: 4395

int a=4,b=2;
a=b<<a+b>>2;

Here b is 2 == (0000 0000 0010)

a = 2<<(4+2)>>2; // as ADD(+) is having higher precedence so first we will solve addtion.
a = 2 << 6 >> 2;

a = ((2 << 6) >> 2); //<<  >>, Associativity (left-to-right) so first solve (2 << 6).

Shifting 6 bits to left

After solving 2<<6  (0000 1000 0000)  == 128  
                          ^^^^ ^^   <-- left  

Shifting 2 bits to right

Now 128>>2  (0000 0010 0000)  == 32.  
        Right -->  ^^

Upvotes: 3

Related Questions