What does this function do?

Discussion in 'C Programming' started by Paul Morrison, May 3, 2005.

  1. Hi

    I have found a function that outputs an 8 bit value in reverse order, but am
    not really sure how it works. Would anyone please be kind enough to explain
    it?

    /* Return an unsigned char that contains the bit pattern in c

    * in the reverse order. For example, if c is 01101011 then

    * the value returned should be 11010110. Assume that a char

    * variable is always 8 bits.

    */

    unsigned char reverse_bits(unsigned char c)

    {

    unsigned char y = 0;



    y += (x & 0x80) >> 7;

    y += (x & 0x40) >> 5;

    y += (x & 0x20) >> 3;

    y += (x & 0x10) >> 1;

    y += (x & 0x01) << 7;

    y += (x & 0x02) << 5;

    y += (x & 0x04) << 3;

    y += (x & 0x08) << 1;



    return y;

    }


    Thanks for your help.

    --
    Paul Morrison
     
    Paul Morrison, May 3, 2005
    #1
    1. Advertising

  2. Paul Morrison

    pete Guest

    Paul Morrison wrote:
    >
    > Hi
    >
    > I have found a function that outputs
    > an 8 bit value in reverse order,
    > but am not really sure how it works.
    > Would anyone please be kind enough to explain it?
    >
    > /* Return an unsigned char that contains the bit pattern in c
    >
    > * in the reverse order. For example, if c is 01101011 then
    >
    > * the value returned should be 11010110. Assume that a char
    >
    > * variable is always 8 bits.
    >
    > */
    >
    > unsigned char reverse_bits(unsigned char c)
    >
    > {
    >
    > unsigned char y = 0;
    >
    > y += (x & 0x80) >> 7;


    Decide if it's c or x, and then
    work it out by pencil and paper.


    unsigned char bit_rev(unsigned char byte)
    {
    unsigned hi_mask, lo_mask;

    hi_mask = ((unsigned char)-1 >> 1) + 1;
    lo_mask = 1;
    do {
    if (!(byte & hi_mask) != !(byte & lo_mask)) {
    byte ^= hi_mask | lo_mask;
    }
    hi_mask >>= 1;
    lo_mask <<= 1;
    } while (hi_mask > lo_mask);
    return byte;
    }

    --
    pete
     
    pete, May 3, 2005
    #2
    1. Advertising

  3. Paul Morrison

    Guest

    unsigned char bit_rev2(unsigned char byte)
    {
    unsigned i, j, rev_byte = 0;
    for (i = 0; i < 8; i++)
    {
    j = byte & (1 << i)?1:0;
    rev_byte |= j << (7 - i);
    }
    return rev_byte;
    }
     
    , May 3, 2005
    #3
  4. Paul Morrison

    Jason Curl Guest

    Paul Morrison wrote:
    > Hi
    >
    > I have found a function that outputs an 8 bit value in reverse order, but am
    > not really sure how it works. Would anyone please be kind enough to explain
    > it?
    >
    > /* Return an unsigned char that contains the bit pattern in c
    > * in the reverse order. For example, if c is 01101011 then
    > * the value returned should be 11010110. Assume that a char
    > * variable is always 8 bits.
    > */
    > unsigned char reverse_bits(unsigned char c)
    > {
    > unsigned char y = 0;
    > y += (x & 0x80) >> 7;
    > y += (x & 0x40) >> 5;
    > y += (x & 0x20) >> 3;
    > y += (x & 0x10) >> 1;
    > y += (x & 0x01) << 7;
    > y += (x & 0x02) << 5;
    > y += (x & 0x04) << 3;
    > y += (x & 0x08) << 1;
    > return y;
    > }


    There's a bug, it doesn't work. Maybe this is because 'x' is actually
    supposed to be 'c'?

    Hint:
    0x80 = 10000000
    0x40 = 01000000
    0x20 = 00100000
    0x10 = 00010000
    0x08 = 00001000
    0x04 = 00000100
    0x02 = 00000010
    0x01 = 00000001

    The '>>' operator shifts bits to the right, filling in new bits on the
    left with zero. The number after this operator is how many bits to shift.

    The '&' is the bitwise AND operator

    So what would we get for the first line, where c = abcdefgh

    y = 0 + (abcdefgh & 1000000) >> 7
    = a0000000 >> 7
    = 0000000a

    Repeat this for the next 7 lines and you should see how it works.

    >
    > Thanks for your help.
    >
    > --
    > Paul Morrison
     
    Jason Curl, May 3, 2005
    #4
  5. Paul Morrison

    pete Guest

    wrote:
    >
    > unsigned char bit_rev2(unsigned char byte)
    > {
    > unsigned i, j, rev_byte = 0;
    > for (i = 0; i < 8; i++)
    > {
    > j = byte & (1 << i)?1:0;
    > rev_byte |= j << (7 - i);
    > }
    > return rev_byte;
    > }


    The first one posted by Paul Morrison was interesting
    because it had no conditional operations.
    The one I posted, reversed the bit order of any width byte.

    --
    pete
     
    pete, May 4, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. schaf
    Replies:
    0
    Views:
    430
    schaf
    May 29, 2005
  2. Peng Yu
    Replies:
    4
    Views:
    352
    peter koch
    Sep 20, 2008
  3. Weng Tianxiang
    Replies:
    7
    Views:
    1,290
    Paul Uiterlinden
    Sep 11, 2009
  4. avasilev
    Replies:
    4
    Views:
    578
    avasilev
    Dec 22, 2011
  5. Stefan Mueller
    Replies:
    23
    Views:
    204
    Lasse Reichstein Nielsen
    Dec 14, 2009
Loading...

Share This Page