假设我有一个字符数组,我希望每个字节向左移N位,向左移,所以只有第一个字符的N位丢失。
示例:左移3位的kxmo
应变为X@hx
这就是我目前所拥有的,但它没有按预期工作:
#include <stdio.h>
int main(void) {
//shift the array with length *len* *shift* bits to the left
int len = 4, shift = 3;
unsigned char a[len] = "kxmo";
unsigned char b[len]; //X@hx
unsigned char tmp = 0, tmp2 = 0;
for(int i = len - 1; i > 0; i--) {
tmp = 0 | (a[i] << shift);
b[i] = a[i];
tmp2 = 0 | (a[i - 1] << shift);
b[i - 1] = (a[i - 1] << shift) ^ tmp;
}
printf("old: %s | new: %s\n", a, b);
return 0;
}
我在哪里失败?
编辑:
这就是我现在要做的事:old: kxmo | new: �xmo
答案 0 :(得分:1)
这样的事情怎么样(假设0&lt; = shift
&lt; 8):
#define BITS_IN_BYTE 8
for(int i = len - 1; i > 0; i--)
{
b[i] = a[i] << shift;
b[i - 1] = (a[i - 1] << shift) | (a[i] >> (BITS_IN_BYTE - shift));
}
我没有检查它,但我希望它会做你想要的。
修改强>
好的,我检查了它,它做了你期望的事。
注 - &gt;您需要将len
设置为5而不是'\0'
设置为4。另请注意,第一次迭代(b[i] = a[i] << shift;
)将在'\0'
上完成,但由于其值为0,因此可以。
答案 1 :(得分:1)
首先,想象用铅笔和纸做。假设您要将两个字节移位三位,首先是字节abcdefgh
,ijklmnop
,并且您希望以defghijk
,lmnop000
结束。< / p>
为了做到这一点,你需要从第二个字节中提取00000ijk
,并将OR
提取到移位后的第一个字节。为此,您需要将第二个字节按8-shift
移至右,并使用00000111
屏蔽结果,即设置最后shift
位到1
。可以通过将1
向左移shift+1
次,生成00001000
并从结果中减去1
来构建此蒙版。
以下是如何做到这一点:
char b1 = 'k';
char b2 = 'x';
int shift = 3;
int carry = 0, nextCarry;
nextCarry = (b1 >> (8-shift)) & ((1<<(shift+1))-1);
b1 <<= shift;
b1 |= carry;
carry = nextCarry;
现在对b2
执行相同操作:
nextCarry = (b2 >> (8-shift)) & ((1<<(shift+1))-1);
b2 <<= shift;
b2 |= carry;
carry = nextCarry;
如果在循环中执行此操作,则可以获得所需的结果。