简体   繁体   中英

Bit manipulation; Converting a 16-bit value into an array of 16 Boolean values? C language

I am reading over some code and I finally need to figure out how this function works. I understand what it is used for and why it is used, but further than that, its magic.

From what I understand the function takes in a value that had all the info compressed into it. So instead of having 16 integers that only hold the value 0 or 1, it packs each 0 or 1 value into the bits of the integer. And this function takes those bits out and puts them each into a char.

The function is called like so

DecompressInputs(DigOut[0], &input[64]);

With DigOut and input being an arrays defined as such

UWORD DigOut[2];
char input[NUM_INPUTS]; // NUM_INPUTS = 80

And the function itself

/*===============================================*/
/* Name: DecompressInputs                        */
/* Purpose: Convert a 16 bit value into an array */
/*  of 16 boolean values.                        */
/*===============================================*/
static __inline__ void DecompressInputs(int bits,char *input)
{
    char i = 16;
    while(i)
    {
        if(bits & 0x0001)
            *input++ = 0x0a5;
        else
            *input++ = 0x000;

        bits = bits >> 1;   
        i-=1;
    }
}

The function checks for the LSB in bits ( if(bits & 0x0001) ). If that bit is set, the first char in input is set to '\\xa5' (whatever character that might be), otherwise to '\\0 . Then input is incemented, so that in the next loop the second char of the original array will be set and bits is shifted ( bits = bits >> 1; ) so the next loop will check for the 2nd LSB of the original value. That is performed 16 times to decompress 16 bits.

Let's have an example:

bits = 0x0005 (binary 0000 0000 0000 0101)

then we have

  1. bits & 0x0001 is true ==> input[0] = '\\xa5'

    bits = bits >> 1 ==> bits = 0x0002 ( binary ... 0010)

  2. bits & 0x0001 is false ==> input[1] = '\\x00' (regarding the original input)

    bits = bits >> 1 ==> bits = 0x0001 ( binary ... 0001)

  3. bits & 0x0001 is true ==> input[2] = '\\xa5'

    bits = bits >> 1 ==> bits = 0x0000 ( binary ... 0000)

.. and so on

Okay, so lets try to explain what's going on here.

First thing first, I believe that static __inline__ void DecompressInputs(int bits,char *input) should be updated to static __inline__ void DecompressInputs(int bits,char *output) because it looks more like an output value than an input one: however, this is detail.

Lets try to make it a bit clearer:

static __inline__ void DecompressInputs(int bits,char *output)
{
    char i = 16;
    while(i)
    {
        /* This will be true if the lowest bit of bits is 1. Otherwise, this is false */
        if(bits & 0x0001)
        {
         /* For whatever reason, you chose 0x0a5 to represent a bit whose value is 1. We write that value to the char pointed by output */
            *output = 0x0a5;
         /* Now that the value has been written, increment output so the next write will go the next char */
            output++;
        }
        else
        {
          /* Same here, but we store 0x00 instead */
            *output = 0x000;
            output++;
        }

        // Now we bitshift bits, so the next time we do bits & 0x0001, we will check for the second bit of the original integer
        bits = bits >> 1;   
        i-=1;
    }
}

This version of the code might be a little easier to understand because it doesn't rely on modifying values as much:

static __inline__ void DecompressInputs(int bits, char *output)
{
    for (int bit = 0; bit < 16; ++bit)
    {
        int mask = 1 << bit;
        if (bits & mask)
            output[bit] = 0x0a5;
        else
            output[bit] = 0;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM