我想将字节数组的内容向左移动12位。
例如,从这个uint8_t shift[10]类型的数组开始:

{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xBC}

我想向左移动12位,结果是:
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xC0, 0x00}

最佳答案

为投手欢呼!
这段代码的工作原理是每字节向前看12位,然后向前复制正确的位。12位是下一个字节的下半部分(nybble),2个字节的上半部分。

unsigned char length = 10;
unsigned char data[10] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0A,0xBC};
unsigned char *shift = data;
while (shift < data+(length-2)) {
    *shift = (*(shift+1)&0x0F)<<4 | (*(shift+2)&0xF0)>>4;
    shift++;
}
*(data+length-2) = (*(data+length-1)&0x0F)<<4;
*(data+length-1) = 0x00;

贾斯汀写道:
@迈克,你的解决方案行得通,但没有用。
好吧,我想说一个正常的移位操作就是这样做的(称为溢出),只是让多余的位从右边或左边掉下来。它很简单,如果你想携带-只要保存12位之前,你开始转移。也许你想要一个循环移位,把溢出的部分放回底部?也许你想重新分配数组并使其更大?将溢出返回给调用方?如果非零数据溢出,返回布尔值?你必须定义进位对你意味着什么。
unsigned char overflow[2];
*overflow = (*data&0xF0)>>4;
*(overflow+1) = (*data&0x0F)<<4 | (*(data+1)&0xF0)>>4;
while (shift < data+(length-2)) {
    /* normal shifting */
}
/* now would be the time to copy it back if you want to carry it somewhere */
*(data+length-2) = (*(data+length-1)&0x0F)<<4 | (*(overflow)&0x0F);
*(data+length-1) = *(overflow+1);

/* You could return a 16-bit carry int,
 * but endian-ness makes that look weird
 * if you care about the physical layout */
unsigned short carry = *(overflow+1)<<8 | *overflow;

10-02 04:01