将N位移位整个字符阵列

时间:2015-09-05 10:59:24

标签: c bit-manipulation bit-shift

假设我有一个字符数组,我希望每个字节向左移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

2 个答案:

答案 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)

首先,想象用铅笔和纸做。假设您要将两个字节移位三位,首先是字节abcdefghijklmnop,并且您希望以defghijklmnop000结束。< / 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;

如果在循环中执行此操作,则可以获得所需的结果。

Demo.