Search code examples
cbitwise-operatorsbitbit-shift

Can anyone explain me this line? c |= 1 << i;


I recently started C and for some reasons I couldn't get this line c |= 1 << i;

the purpose of this function I found online is to get the least significant bit from an array and then combine it, and return as a byte.

unsigned char getlsbs(unsigned char* p)
{
        int i;
        unsigned char c = 0;
        for(i = 0; i < 8; i++)
        {
                int a = p[i] & 1;
                if(a)
                {
                        c |= 1 << i;
                }
        }
        return c;
}

c |= 1 << i; would be the same as c = c | 1 << i; correct?

Could anyone explain with the example in 1s and 0s? I think it will be very helpful. Thanks!


Solution

  • Well,

    1<<i 
    

    should be 1 followed by i zeros (binary)--so

    1<<0 = 0001
    1<<1 = 0010
    1<<2 = 0100
    

    When that is ORed with what's in C it means to force-set that bit, so:

    if you take 0000 | 0010 you'll get 0010
    
    c val| mask = result
    --------------------
    0010 | 0010 = 0010 as well
    1111 | 0010 = 1111 (No change if the bit is already 1)
    1101 | 0010 = 1111 (Just sets that one bit)
    xxxx | 0010 = xx1x (All the other bits remain the same)
    

    Finally it stores the result back into c.

    So essentially it sets the ith bit in c (starting from the least significant as zero).

    Further detail:

    // Loop through the first 8 characters in p
    for(i = 0; i < 8; i++)
    {
        // Grab the least significant bit of the i'th character as an int (1 or 0)
        int a = p[i] & 1;
        // If it happens to be set (was a 1)
        if(a)
        {
            // Set the corresponding (i'th) bit in c
            c |= 1 << i;
        }
    }
    

    So if the first value of p has a lsb of 1, the lsb of c will be 1

    if the second byte in p has a lsb of 1, the second bit of c will be 1

    etc.

    the result is that each bit of C will take the value of least significant bit of each of the first 8 bytes of P

    I bet it could be coded more densely though if I really wanted to try, but this is probably targeting performance :)