位操作;将16位值转换为16个布尔值的数组?C语言

位操作;将16位值转换为16个布尔值的数组?C语言,c,bit-manipulation,bit,C,Bit Manipulation,Bit,我正在阅读一些代码,最后我需要弄清楚这个函数是如何工作的。我了解它的用途和使用原因,但除此之外,它还有魔力 据我所知,函数接受一个值,该值将所有信息压缩到函数中。因此,它不需要16个只保存值0或1的整数,而是将每个0或1值打包到整数的位中。这个函数将这些位取出,并将它们分别放入一个字符中 这个函数是这样调用的 DecompressInputs(DigOut[0], &input[64]); DigOut和input是这样定义的数组 UWORD DigOut[2]; char input

我正在阅读一些代码,最后我需要弄清楚这个函数是如何工作的。我了解它的用途和使用原因,但除此之外,它还有魔力

据我所知,函数接受一个值,该值将所有信息压缩到函数中。因此,它不需要16个只保存值0或1的整数,而是将每个0或1值打包到整数的位中。这个函数将这些位取出,并将它们分别放入一个字符中

这个函数是这样调用的

DecompressInputs(DigOut[0], &input[64]);
DigOut和input是这样定义的数组

UWORD DigOut[2];
char input[NUM_INPUTS]; // NUM_INPUTS = 80
以及函数本身

/*===============================================*/
/* 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;
    }
}

该函数检查
位中的LSB
if(bits&0x0001)
)。如果设置了该位,则
输入
中的第一个字符设置为
'\xa5'
(无论可能是什么字符),否则设置为
'\0
。然后启动
输入
,以便在下一个循环中设置原始数组的第二个字符,并移动
位=位>>1;
),以便下一个循环检查原始值的第二个LSB。执行16次以解压缩16位

让我们举个例子:

位=0x0005(二进制0000 0101)

那么我们有

  • 位&0x0001
    为真==>输入[0]='\xa5'


    位=位>>1
    ==>位=0x0002(二进制…0010)

  • 位&0x0001
    为假==>输入[1]='\x00'(关于原始输入)


    位=位>>1
    ==>位=0x0001(二进制…0001)

  • 位&0x0001
    为真==>输入[2]='\xa5'


    位=位>>1
    ==>位=0x0000(二进制…0000)


  • 。。依此类推好的,让我们试着解释一下这里发生了什么

    首先,我认为应该将
    static\uuuu inline\uuuu void decompressionnputs(int位,char*input)
    更新为
    static\uuu inline\uuuuu void decompressionnputs(int位,char*output)
    ,因为它看起来更像是一个输出值,而不是一个输入值:然而,这是一个细节

    让我们试着让它更清楚一点:

    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;
        }
    }
    

    此版本的代码可能更容易理解,因为它不太依赖于修改值:

    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;
        }
    }
    
    static\uuuuu内联\uuuuu无效解压缩输出(int位,char*输出)
    {
    用于(整数位=0;位<16;++位)
    {
    
    int mask=1不确定为什么要用0xA5表示on位,但剩下的很简单:只需循环16次,屏蔽低位并将值右移以将下一位移动到位。函数的输出名为“input”也是非常糟糕的形式(:-)是的,我使用的所有代码都有不好的形式。所以0x0A5对你和我来说都是陌生的?这就是我最感兴趣的地方,我只是不明白为什么会这样,但仍然不明白。--函数中的I=16,因为UWORD是16位长的;很明显….?
    bits=bits>.1
    bits=>1
    0xA5是“Yen”符号。不知道它在那里做什么。
    0x0a5
    0x000
    部分不知怎的告诉我,
    char
    在OP的平台上有12位长……不确定是否是这样。(如果不是,我不可能理解OP为什么附加了一个额外的0。无论如何……)