ps:想看结论的直接跳到最后即可,本文的二进制首位指的最右边第一位,而最后一位指的最左边第一位
左移
运算符:<<
运算符后接整数数字,代表左移多少位。
计算方式:整数转换为的二进制数向左移 n 位,右边多出来的位数用 0 补齐,超出的位数直接舍去,比如二进制数 0000 0001 左移 1 位得 0000 0010
注意:
- 在计算机中,若不是无符号整数,则左边第一位是符号位,当进行移位操作时符号位不会被移动
- 对于 int 类型的左移,对于移位的操作数只取前 5 位二进制数,即最高左移 31 位当超过 31 又将从头计算也就是第左移第 32 位等于左移 0 位,以此往复,比如左移 64 位也等于左移 0位(当超过位移数超过 32 时c++会警告算术溢出但不会报错)。
至于为什么是最高能移 31 位,c++中 int 类型除去符号位只有 31 位,但是为了严格起见(防止编译器不同引起的错误)移位运算符最多可移动 sizeof(int) * 8 - 1位
例:2 左移 256 位,按理来说应该为 0 ,但 256 的二进制数为 0010 0000 取前 5 位就是 0,于是左移 0 位,结果仍为 2。
对于移位负数位,取其补码的前 8 位为操作数即可
例:-255补码的前 5 位为0 0001,左移1 位,结果为4(对于负数,vs会警告算术溢出,但不会报错)
使用方法:
- x * 2n = x << n,即在 x 的二进制数前加了个 0
例:3 左移 2 位, 相当于 3 * 22 = 12
右移
运算符:>>
运算符后接整数数字,代表右移多少位
计算方式:整数转换为的二进制数向右移 n 位,左边多出来的位数用 0 补齐(当被操作数为负数可能补 1,与编译器有关,c++负数中用 1 补位),超出的位数直接舍去,比如二进制数 0000 0001 右移 1 位得 0000 0000
同样,右移也只取操作数的前 5 位
负数也一样,就不举例了
使用方法:
- 右移运算符和左移相反,用于除法,x / 2n = x >> n。
当 x 为偶数时相当于删掉了右边的 n 个0,为奇数时,就是整数除法中的结果向下取整
例:4 右移 1 位,相当于 4 / 21 = 2
取反
运算符:~
计算方式:将二进制中的 0 全变成 1,1 全变成 0
使用方法:
- 当 x 是有符号整数时,-x = ~x + 1 = ~(x - 1)。
负数的补码等于原码取反 +1,所以当正数被取反后要变成负数的原码经过了 -1 再取反,要算 -x 得将减去的 1 加回来所以式子为取反后 +1。若 x 为负数同理,内存中存的 x 的补码