如何连接按顺序存储在数组中的高位和低位半字节?

时间:2009-01-09 10:14:42

标签: c arrays bit-shift

我有一个包含半字节列表的数组:

{0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, ...}

我希望通过左移上部半字节并将其与下部半字节连接,将相邻的半字节组合成单个字节。输出应如下所示:

{0xab, 0xcd, 0xef, ...}

如何在C中完成此操作?

4 个答案:

答案 0 :(得分:7)

这样的东西
char *input, *output;
int i;
...
for(i=0; i<len; i+=2) {
  output[i/2]=(input[i]<<4) | input[i+1];
}

将输出作为数组提供,至少是输入的一半,并且输入中没有设置高半字节。

答案 1 :(得分:4)

如果没有为您编写完整的代码,这里有一个提示:

unsigned int Nibble1 = 0x0A;
unsigned int Nibble2 = 0x0B;

unsigned int Result = (Nibble1 << 4) | Nibble2; // Result = 0xAB

然后你只需要编写一个循环,一次遍历输入数组两个元素并写入输出数组。

我希望这有帮助!

答案 2 :(得分:2)

只是为了踢,这是一个生成连接数组而不使用第二个数组的版本。它只是用新值覆盖原始数组的前半部分:

char * writePtr = originalArray;
char * readPtr = originalArray;
while (readPtr < (originalArray + arraySize))
{
    *writePtr = (*readPtr << 4) | *(readPtr + 1);
    readPtr += 2;
    writePtr++;
}

答案 3 :(得分:0)

可能这会对你有所帮助,它不仅仅是一个简单的关于半字节的艺术(上/下)

该系统称为二进制编码十进制或BCD,它也占用半字节。在BCD中,二进制模式1010到1111不代表有效的BCD编号,不能使用。

从Decimal到BCD的转换非常简单。您只需将十进制数的每个数字分配给一个字节,并将0到9转换为0000 0000到0000 1001,但是您不能像将十进制转换为二进制那样执行重复除法。

让我们看看这是如何运作的。确定十进制数5,319的BCD值。由于我们的十进制数有四位数,因此我们的BCD编号中有四个字节。他们是:

Final Number is -5319

    Thousands               Hundreds             Tens                    Units 
       [5]                      [3]               [1]                      [9] 
    0 0 0 0 0 1 0 1      0 0 0 0 0 0 1 1     0 0 0 0 0 0 0 1     0 0 0 0 1 0 0 1 

由于计算机存储至少需要1个字节,因此您可以看到每个BCD编号的高半字节是浪费的存储空间。 BCD仍然是加权位置编号系统,因此您可以执行数学运算,但我们必须使用特殊技术才能获得正确的答案。


PACKED BCD

由于磁盘和RAM中的存储非常有价值,我们希望消除这种浪费的存储。这可以通过打包BCD号码来完成。在打包的BCD编号中,每个半字节具有从小数点开始的加权位置。因此,我们只需要2个字节,一半的存储空间,而不需要4个字节来存储BCD号5319。我们数字的高字节的高半字节将存储THOUSANDS值,而高字节的低半字节将存储HUNDREDS值。同样,低字节将TENS值存储在高半字节中,而UNITS数字存储在低半字节中。因此,我们之前的例子是:

Thousands - Hundreds          Tens - Units 
        [53]                       [19] 
0 1 0 1 0 0 1 1              0 0 0 1 1 0 0 1