为什么将整数左移 24 位会产生错误的结果?

int*_*ing 2 c bit-shift bit bitwise-operators

我尝试将 32 位整数左移 24:

char *int_to_bin(int num) {
    int i = 0;
    static char bin[64];
   
    while (num != 0) {
        bin[i] = num % 2 + 48;
        num /= 2;
        i++;
    }
    bin[i] = '\0';
    return (bin);
}

int main() {
    int number = 255;
    printf("number: %s\n", int_to_bin(number));
    printf("shifted number: %s\n", int_to_bin(number << 24));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出

number: 11111111
shifted number: 000000000000000000000000/
Run Code Online (Sandbox Code Playgroud)

我左移 23 位,得到以下结果:

0000000000000000000000011111111
Run Code Online (Sandbox Code Playgroud)

那么为什么会这样呢?错误结果末尾的“/”是怎么回事?

Nat*_*dge 6

两件事情:

  • 如果number值为 255,则number << 24数值为 4278190080,这会溢出一个 32 位有符号整数,其最大可能值为 2147483647。有符号整数溢出是 C 中未定义的行为,因此结果可能是任何结果。

    在这种情况下可能发生的情况是移位的结果为负。当num为负数时,num % 2可能会取值-1,因此您将字符 47 存储在字符串中,即/

    位移位数学通常更适合使用unsigned类型,其中溢出是明确定义的(它环绕并且位只是从左侧移位并消失)并且num % 2只能是 0 或 1。(或者num & 1改为写入。)

  • 您的int_to_bin例程将最低有效位放在字符串的开头(在左侧),因此结果与人们通常编写数字的方式相反(最低有效位在右侧)。您可能想重写它。