Search code examples
cbit-shift

Left shift bits in c


I have been making some stupid test about bits manipulation, and I found this issue. I execute this code:

int main(){
  unsigned int i;
  for (i=1; i<34; i++)
  {
    unsigned long temp = i;
    unsigned long mul = 1;
    unsigned long val;
    unsigned long one = 1;

    // Way 1
    while (temp--)
      mul = mul << one;

    // Way 2
    val = (one<<i);

    printf(" \n 1<<%i \n mul: 0x%X , val: 0x%X\n",i, mul, val); 
  }
}

Of course, I know that when i>31, an overflow will be produced. I think that both parts of code (way1 and way2) should output the same result. But I get this (at the end):

 /* ... correct results from i=1 to i=31 ... */
 1<<30 
 mul: 0x40000000 , val: 0x40000000 

 1<<31 
 mul: 0x80000000 , val: 0x80000000 

 1<<32 
 mul: **0x0** , val: **0x1** 

 1<<33 
 mul: **0x0** , val: **0x2**

Why, if both instructions are left shifts, the program produces different outputs? It seems that the part way2 produces a round shift, but I don't know why, I really think that "mul" gets always the correct value.

I compile under a Intel 32bits machine, gcc version 4.4.7


Solution

  • In case of

    val = (one<<i);
    

    when i gets greater than or equal to 32, the behavior is undefined.

     

    However, in case of

    while (temp--)
       mul = mul << one;
    

    for shifts more than 32, it will shift zero and the result is defined (zero).