c - 将整个字符数组移位 N 位

标签 c bit-manipulation bit-shift

假设我有一个字符数组,我想将每个字节向左移动 N 位,向左移动,因此只有第一个字符的 N 位会丢失。

示例:kxmo 向左移动 3 位应成为 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 |新:�xmo

最佳答案

首先,想象一下用铅笔和纸来做这件事。假设您要将两个字节移动三位,您以字节 abcdefghijklmnop 开始,并希望以 defghijklmnop000.

为此,您需要从第二个字节中提取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.

关于c - 将整个字符数组移位 N 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32412281/

相关文章:

c - AIX loadquery() 返回值解释(也是 64 位模式下的 SEGV)

ios - 快速读取任意数量位的方法

java - 尝试在 Java 中对两个 int 进行按位 AND,但编译器尝试将它们用作 bool

c - 在 C 语言中 if(x) 到底解析成什么?

C gcc编译问题和makefile

verilog - 算术移位充当逻辑移位,无论有符号变量如何

c - 为什么对 C 枚举定义中的值使用 Bitwise-Shift 运算符?

java - Java整数左移的奇怪结果

c - ANSI C - 使用动态数组创建的嵌套 BER TLV 元素的释放

c# - 合并2个字节