左移

int a = 1;      // 0001b
int b = a << 1; // 0010b

std::cout << "a = " << a << ", b = " << b << std::endl;

输出

a = 1, b = 2

为什么

左位移位将左手值(a)的位移位右侧指定的数字(1),基本上用 0 来填充最低有效位,因此将 5(二进制 0000 0101)的值移到左边 4 时间(例如 5 << 4)将产生 80(二进制 0101 0000)的值。你可能会注意到,将值向左移 1 次也与将值乘以 2 相同,例如:

int a = 7;
while (a < 200) {
    std::cout << "a = " << a << std::endl;
    a <<= 1;
}

a = 7;
while (a < 200) {
    std::cout << "a = " << a << std::endl;
    a *= 2;
}

但应该注意左移位操作会将所有位向左移位,包括符号位,例如:

int a = 2147483647; // 0111 1111 1111 1111 1111 1111 1111 1111
int b = a << 1;     // 1111 1111 1111 1111 1111 1111 1111 1110

std::cout << "a = " << a << ", b = " << b << std::endl;

可能的输出:a = 2147483647, b = -2

虽然有些编译器会产生看似预期的结果,但应该注意的是,如果你将 shift 符号移位以使符号位受到影响,则结果是未定义的。如果你希望移位的位数是负数或大于左侧类型可以容纳的位数,则也未定义,例如:

int a = 1;
int b = a << -1;  // undefined behavior
char c = a << 20; // undefined behavior

除非特别指定使用按位分配复合运算符 <<=,否则按位左移不会更改原始值的值:

int a = 5;  // 0101b
a <<= 1;    // a = a << 1;