我有一个包含半字节列表的数组:
{0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, ...}
我希望通过左移上部半字节并将其与下部半字节连接,将相邻的半字节组合成单个字节。输出应如下所示:
{0xab, 0xcd, 0xef, ...}
如何在C中完成此操作?
答案 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