左移给我奇怪的结果

Left shift gives me strange results

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    printf("left shift 1 = %d\n", 1 << 1);
    printf("left shift 2 = %d\n", 1 << 2);
    printf("left shift 3 = %d\n", 1 << 3);
    printf("left shift 4 = %d\n", 1 << 4);
    printf("left shift 5 = %d\n", 1 << 5);
    printf("left shift 6 = %d\n", 1 << 6);
    printf("left shift 7 = %d\n", 1 << 7);

    return 0;
}

我得到了这样的输出:

left shift 1 = 2
left shift 2 = 4
left shift 3 = 8
left shift 4 = 16
left shift 5 = 32
left shift 6 = 64
left shift 7 = 128

1号和2号好像是对的,但是3号到7号其他的号怎么了?

这一点也不奇怪。对于无符号整数(通常 通常 对于不侵犯符号位的有符号整数,但这不是标准强制要求的),左移基本上是加倍值。

这正是您所看到的:

1 << 0 = 0000 0001 =   1
1 << 1 = 0000 0010 =   2
1 << 2 = 0000 0100 =   4
1 << 3 = 0000 1000 =   8
1 << 4 = 0001 0000 =  16
1 << 5 = 0010 0000 =  32
1 << 6 = 0100 0000 =  64
1 << 7 = 1000 0000 = 128

左移操作n << 1实际上是将左操作数乘以2。你程序的结果显示了这一点。

假设您有一个名为 n 的对象,类型为 char

0000 0001

然后 n << 1 给出

0000 0010 

十进制表示为2

n << 2 给出

0000 0100

十进制表示为4

n << 3 给出

0000 1000

也就是十进制是8。

以此类推

您所体验的是移位运算符的正确行为。

让我们从说明一个字节的十进制表示开始:

ByteDecValue = 
    bit0 * 2^0 +
    bit1 * 2^1 +
    bit2 * 2^2 +
    bit3 * 2^3 +
    bit4 * 2^4 +
    bit5 * 2^5 +
    bit6 * 2^6 +
    bit7 * 2^7

所以比如00010010b字节对应的十进制值为2^4 + 2^1 = 18 dec.

只有一个字节为1时,会出现一个有趣的特殊情况。从上面的公式推导出我们可以说

ByteDecValue_bit_N = 2^N

2^0 = 1 << 0 = 0000 0001
2^1 = 1 << 1 = 0000 0010
2^2 = 1 << 2 = 0000 0100
2^3 = 1 << 3 = 0000 1000
2^4 = 1 << 4 = 0001 0000
2^5 = 1 << 5 = 0010 0000
2^6 = 1 << 6 = 0100 0000
2^7 = 1 << 7 = 1000 0000

这正是您的体验:通过将 1 向左移动 N 次,您在位置 N 得到一个 1,因此幂为 2^N。

注意: 您的测试也可以通过打印 1 << 0 的值来完成。在那种情况下,你会得到 2^0 = 1。完全不移位意味着保持原始值。