【问题标题】:C: Computing a series of bits spanned over several bytesC:计算跨越多个字节的一系列位
【发布时间】:2013-08-25 05:35:26
【问题描述】:

我有一个 unsigned char 字节数组,例如:

unsigned char[20] = {0xff, 0x1a, 0x70, 0xa9, ...}

我现在想对该数组的 x 个连续位执行计算(使用 x > 8;例如 x = 15)。特别是,我想对每 15 位执行一次多数投票,这将返回一个位。随后,返回的单个位应再次转换为无符号字符字节。

我已经实现了多数投票算法。我还为整个问题实现了一个简单的算法,它是这样工作的:

  1. 将字节数组转换为位数组(还有 unsigned char[] 保存零和一)
  2. 遍历位数组并将每一系列 x 位传递给多数投票函数
  3. 也在位数组中收集多数投票结果 (unsigned char[])
  4. 循环这个位数组并使用按位运算从每个 8 位序列中构造字节。

对我来说,这似乎很直观,但同时也很麻烦。

您是否看到任何优化的可能性,或者您能否给出一个更简洁的算法?

最好的问候, P.

【问题讨论】:

  • 您能解释一下为什么您不只使用具有 1 个未使用填充位的 16 位块吗?事实上,我希望这是最初的意图,结果存储在第 16 位中。

标签: c bit-manipulation


【解决方案1】:

您可以使用类似的函数获取数组的下一位

 int nextBit( unsigned char [] arr, int *pByte, size_t nBytes, int *pBit ) 
 {
      int result;

      if( *pByte >= nBytes ) {
          // Padding, neccessary if nBytes % 15 != 0
          return 0;
      } else {
          result = ( arr[*pByte] >> (*pBit) ) & 0x1;
          if( *pBit == 7 ) {
              (*pByte)++;
              *pBit = 0;
          } else {
              (*pBit)++;
          }
          return result;
      }
 }

和循环:

 int byte=0, bit=0;
 int result;
 int i;

 while( byte < sizeof( arr ) ) {
     for( i=0; i<15; i++ ) {
         result = nextBit( arr, &byte, sizeof( arr ), &bit );
         // do the majority voting
     }
 }

可以创建一个非常相似的函数来直接创建一个多数位数组

【讨论】:

    【解决方案2】:

    您可以将每个字节移位为 17 位(并将它们存储在 17 个字节中)。

    uint8_t bits[17];
    bits[0] = !!(bytes[0] & 128);
    bits[1] = !!(bytes[0] & 64);
    bits[2] = !!(bytes[0] & 32);
    bits[3] = !!(bytes[0] & 16);
    bits[4] = !!(bytes[0] & 8);
    bits[5] = !!(bytes[0] & 4);
    bits[6] = !!(bytes[0] & 2);
    bits[7] = !!(bytes[0] & 1);
    bits[8] = !!(bytes[1] & 128);
    bits[9] = !!(bytes[1] & 64);
    bits[10] = !!(bytes[1] & 32);
    bits[11] = !!(bytes[1] & 16);
    bits[12] = !!(bytes[1] & 8);
    bits[13] = !!(bytes[1] & 4);
    bits[14] = !!(bytes[1] & 2);
    bits[15] = !!(bytes[1] & 1);
    bits[16] = !!(bytes[2] & 128);
    

    我不确定你想用这些位做什么,但你也可以考虑将这些位存储在一个 32 位整数中:

    uint32_t chunk = (bytes[0] << 9) | (bytes[1] << 1) | (bytes[2] & 1);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 2012-09-14
      • 2016-09-30
      • 1970-01-01
      • 2021-11-13
      • 1970-01-01
      • 2017-01-09
      相关资源
      最近更新 更多