2013-08-21 37 views
0

我想执行格雷编码/上的easurement,其被存储在字符数组解码访问一系列连续的12个比特。因此,我需要访问传递给编码器/解码器的连续12位测量值。C:在字符数组

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.

+0

你是什么意思的“记忆保存方法”?如上所述的打包阵列是最节省内存的方法。如果你想提取每个12位数据值来做一些操作,就像下面的Jongware一样。如果我不知道下一个阶段 –

+0

的输入,那么我无法回答任何问题,哪12位要访问? –

回答

0

未经检验的,从我的头顶,我敢肯定,你可以进一步简化它...

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); 
2

转换的指数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位的倍数?

+0

不要假设char是8位宽,使用CHAR_BIT – maep

+0

@maep:'char'的实际宽度在这里并不重要。该数组以'unsigned char'形式给出,仅包含8位值。对这些字符进行的唯一操作是位移和掩码 - 没有任何措施可以防止它与“9位字符”甚至短语或整数完全一样。 – usr2564301

-1

你可以“解析”的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位。

+1

由于使用错误的printf格式说明符并使用保留名称'uintN_t',并违反了严格的别名规则,导致未定义的行为。位字段的布局也是实现定义的 –