【问题标题】:C: Access consecutive series of 12 bits in a char arrayC:访问 char 数组中连续的 12 位序列
【发布时间】:2013-08-21 08:19:19
【问题描述】:

我想对存储在 char 数组中的 easurement 执行 Golay 编码/解码。因此,我需要访问连续的 12 位测量值,这些测量值会传递给编码器/解码器。

char 数组长 22 字节,如下所示,例如:

unsigned char measurement1[22] =
{0xb5, 0x31, 0xc6, 0x51, 0x84, 0x26, 0x2c, 0x69, 0xfd, 0x9e,
0xef, 0xd4, 0xcf, 0xf1, 0x24, 0xd4, 0xf1, 0x97, 0xe5, 0x81, 
0x02, 0xf8}

目前,我正在将 char 数组转换为相应位的数组并将其传递给编码器。但是,这种方法非常消耗内存,因为位数组也是一个字符数组 - 0 或 1 - 总共有 176 个字节 (22 * 8)。

有没有更节省内存的方法,不依赖于将字节数组转换成一系列位,而是访问连续的12位,然后传递给解码器?

最好的问候, P.

【问题讨论】:

  • “节省内存的方法”是什么意思?像上面这样的打包数组是最节省内存的方法。如果要提取每个 12 位数据值对其进行一些操作,请像下面的 Jongware 一样。如果我不知道下一阶段的输入,我无法回答任何问题
  • 您要访问哪 12 位?

标签: c bit-manipulation


【解决方案1】:

将索引i 转换为不是基于 1 字节的偏移量到 8 位,而是转换为基于 12 位的偏移量。那么这取决于您是索引偶数还是奇数 12 位三元组:

for (i=0; i<22*8/12; i++)
{
    printf ("%03x ", (i & 1) ? measurement1[3*i/2+1]+((measurement1[3*i/2] & 0x0f)<<8) : (measurement1[3*i/2]<<4)+((measurement1[3*i/2+1]>>4) & 0x0f) );
}

这假设您的测量数组是从左到右读取的,即

0xb5, 0x31, 0xc6

翻译成

0xb53 0x1c6

如果您的顺序不同,则需要调整位移位。

您的测量数组是否包含 12 位的倍数?

【讨论】:

  • 不要假设 char 是 8 位宽,使用 CHAR_BIT
  • @maep:char 的实际宽度在这里无关紧要。该数组以unsigned char 给出,仅包含 8 位值。对这些字符进行的唯一操作是位移和掩码——没有什么可以阻止它与“9 位字符”甚至短裤或整数完全相同。
【解决方案2】:

未经测试,在我的脑海中,我相信你可以进一步简化它......

int i = 0, left = 8, v = 0;

do
{
  v = 0;
  switch (left)
  {
     case 8:
     {
        v = measurement1[i++];
        v = (v << 4) | (measurement1[i] >> 4); // please handle end here correctly
        left = 4;
        break;
     }
     case 4:
     {
       v = measurement1[i++] & 0x0F; // lower nibble
       v = (v << 8) | measurement1[i++];  // please handle end here correctly
       left = 8;
       break;
     }
  }
  // Now encode v
} while (i < 22);

【讨论】:

    【解决方案3】:

    您可以将mesurement“解析”为 12 位数组:

    typedef union { // you can use union or struct here
        uint16_t i : 12;
    } __attribute__((packed)) uint12_t;
    printf("%u", ((uint12_t*) mesurement)[0]);
    

    这将打印数组的前 12 位。

    【讨论】:

    • 这会导致未定义的行为,因为使用了错误的 printf 格式说明符,使用了保留名称 uintN_t,并且违反了严格的别名规则。位域的布局也是实现定义的
    猜你喜欢
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 2016-06-19
    • 2014-03-22
    • 2012-01-21
    相关资源
    最近更新 更多