【问题标题】:C: Unpacking a byteC:拆包一个字节
【发布时间】:2010-03-07 17:45:04
【问题描述】:

我问了here 的问题,现在我想扭转这个过程

我有一个代表位模式的 unsigned short,我想要一个 bool[16] 数组,为 unsigned short 中的相应位设置真或假。

目前为止

其中二进制 2 是一个无符号短整数,具有我希望解压缩的位模式。

unsigned short i;
i = 1<<(sizeof(unsigned short) * 8 - 1);

while (i > 0) {
    if (binary2 & i)
        printf("1");
    else
        printf("0");
    i >>= 1;
}

但我似乎遗漏了我的模式中的第一位并转移了其余的位。

【问题讨论】:

  • 请贴出你目前写的代码。人们通常不喜欢只为您编写代码。
  • 我不同意。我回答了我可以回答的任何问题,我相信 SO 旨在成为综​​合答案库。找到所有答案的地方。全部回答,不要判断。
  • 你贴的代码没有拆包。它打印binary2 的二进制表示。
  • 是的,我只是将它打印到控制台,直到我做对了...
  • @Aran:您发布的代码看起来不错 - 您所说的“我似乎遗漏了我的模式中的第一个部分”是什么意思?

标签: c bytearray bit-manipulation


【解决方案1】:
 void get_bits(uint16_t pattern, bool bits[16]) {
    for (int i = 0; i < 16; ++ i)
      bits[i] = (pattern & 1 << i) != 0;
 }

union bit16 {
    uint16_t bit_pattern;
    struct {
        int bit0 : 1;
        int bit1 : 1;
        int bit2 : 1;
        int bit3 : 1;
        int bit4 : 1;
        int bit5 : 1;
        int bit6 : 1;
        int bit7 : 1;
        int bit8 : 1;
        int bit9 : 1;
        int bit10 : 1;
        int bit11 : 1;
        int bit12 : 1;
        int bit13 : 1;
        int bit14 : 1;
        int bit15 : 1;
    } bits;
};

【讨论】:

  • 你确定这里的 union 是可移植的吗?结构的对齐方式可能不同。
  • @Checkers:他可以将短线移到并集的末尾来解决任何对齐问题。
  • 你应该让你的位域明确无符号;否则它们可能最终成为有符号的一位字段!
  • @Robert S. Barnes,顺序重要吗?它们都从同一个地址开始。
  • @Checkers:你说得对,我的手指在输入union,但我的大脑在思考struct
【解决方案2】:

这个怎么样。

void ExtractBits(int pattern, int array[16])
{
   for (int ii = 0; ii < 16; ++ii)
   {
      array[ii] = pattern & 1;
      pattern = pattern >> 1;
   }
}

【讨论】:

    【解决方案3】:

    我真的不明白您为什么要这样做,因为这听起来很慢,但执行此操作的代码应该相当简单。让我首先验证我是否了解您要执行的操作。你有一个无符号短和一个布尔数组。您想将短片中的每一位提取到布尔值中。正确的?如果是这样,这应该是您正在寻找的:

    unsigned short bitmask = (some mask);
    bool bools[sizeof(unsigned short) * 8];
    for(unsigned short i = 0; i < sizeof(unsigned short) * 8; ++i)
    {
        unsigned short bit = 1 << i;
        bools[i] = bitmask & bit;
    }
    

    根据您的应用程序实际执行的操作,我强烈建议对每个位使用枚举,而不是使用布尔值,只需对枚举进行按位运算以获取位的值。你必须小心使用按位运算,因为它们在 CPU 上可能非常慢。

    另外我强烈建议不要使用 Kenny 在他的部分回答中展示的位域,因为我从未在位域不是非常慢的处理器上工作过。

    【讨论】:

      【解决方案4】:

      不是最好的代码,但它可以完成工作。你知道快速和肮脏的东西:)

      typedef unsigned short int Word;
      
      bool get_bit(Word word, size_t pos)
      {
          return (word &= (1 << pos));
      }
      
      void unpack_word(Word word, bool unpacked_bits[])
      {
          for(size_t i = 0; i < sizeof(Word)*CHAR_BIT; ++i)
              unpacked_bits[i] = get_bit(word, i);
      }
      
      int main()
      {
          Word w = 0xF0FF;
          bool bits[sizeof(Word)*CHAR_BIT];
          unpack_word(w, bits);
      }
      

      【讨论】:

      • std:: 不是必需的。问题在于 C,而不是 C++。 (是的,bool 也存在于 C 中 (stdbool.h)。)
      • @KennyTM 谢谢,我忘了问题是关于 C 的:)
      【解决方案5】:

      所以你需要这样的东西;

        for(i = 1, j = 0; i != 0x10000; i <<= 1, ++j)
          result[j] = (binary2 & i) > 0;
      

      例如:

      #include <stdio.h>
      #include <stdlib.h>
      #include <stdbool.h>
      
      bool result[16];
      
      void try(unsigned short binary2) {
        int i,j;
      
        for(i = 1, j = 0; i != 0x10000; i <<= 1, ++j)
          result[j] = (binary2 & i) > 0;
      }
      
      int main(int ac, char **av) {
        int i;
      
        if (ac > 1)
          try(atoi(av[1]));
        for(i = 15; i >= 0; --i)
          printf("%c", result[i]["ft"]);
        printf("\n");
        return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2012-03-23
        • 2017-12-02
        • 1970-01-01
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        • 2014-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多