2

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

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

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

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

我怎样才能在 C 中实现这一点?

4

4 回答 4

7

就像是

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

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

于 2009-01-09T10:22:06.767 回答
6

无需为您编写整个代码,这里有一个提示:

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

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

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

我希望这有帮助!

于 2009-01-09T10:21:56.050 回答
3

只是为了好玩,这是一个不使用第二个数组即可生成串联数组的版本。它只是用新值覆盖原始数组的前半部分:

char * writePtr = originalArray;
char * readPtr = originalArray;
while (readPtr < (originalArray + arraySize))
{
    *writePtr = (*readPtr << 4) | *(readPtr + 1);
    readPtr += 2;
    writePtr++;
}
于 2009-01-09T10:52:41.447 回答
1

可能这会对你有所帮助,它只是关于轻咬的简单文章(上/下)

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

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

让我们看看这是如何工作的。确定十进制数 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 仍然是加权位置数字系统,因此您可以进行数学运算,但我们必须使用特殊技术才能获得正确答案。


打包 BCD

由于磁盘和 RAM 中的存储非常宝贵,我们希望消除这种浪费的存储。这可以通过打包 BCD 数来完成。在打包的 BCD 数字中,每个半字节都有一个从小数点开始的加权位置。因此,不需要 4 个字节来存储 BCD 数字 5319,我们只需要 2 个字节,即存储空间的一半。我们数字的高字节的高半字节将存储 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 
于 2010-03-15T08:42:35.690 回答