c - 如何将字节数组移动 12 位

标签 c arrays bit-shift bitset

我想将字节数组的内容向左移动 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;

Justin wrote:
@Mike, your solution works, but does not carry.

好吧,我会说正常的移位操作就是这样做的(称为溢出),只是让额外的位从右边或左边掉下来。如果您愿意,它很容易携带 - 只需在开始移位之前保存 12 位即可。也许你想要循环移位,将溢出的位放回底部?也许您想重新分配数组并使其更大?将溢出返回给调用者?如果非零数据溢出,返回一个 bool 值?您必须定义进位对您意味着什么。

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;

关于c - 如何将字节数组移动 12 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29437/

相关文章:

c - realloc 和指向 c 结构和函数中的整数比较问题的指针

php - 以 K 为单位计算色温

arrays - 尝试用 Argo 解码数组

c++ - 将文件中的多个输入分隔为偶数或奇数

c++ - 在 C++ 中转换 big-endian long?

c - 了解如何使用 C 中的按位运算符计算数字的尾随零

c - C Linux 中的 SIGABRT

c - 批处理文件启动但在 c 中启动时命令不运行

javascript - 为什么 array[length] 返回列表的第一个元素?

c - 带符号 int 的位移位重置过多