移位运算分为左移(<<)与右移(>>),其中右移又分为逻辑右移与算术右移。三者实现如下: (1)左移:移出去的位丢弃,空缺位(vacant bit)用 0 填充; (2)逻辑右移:移出去的位丢弃,空缺位(vacant bit)用 0 填充; (3)算术右位:移出去的位丢弃,空缺位(vacant bit)用符号位来填充。
以补码 0x10110011 来演示左移、逻辑右移与算术右移。
左移:
逻辑右移:
算术右移:
移位算只能作用于整数,不能作用于浮点数。对于无符号整数与有符号整数,左移操作相同,但右移稍有区别。 (1)对于无符号整数为逻辑右移; (2)对于有符号整数为算术右移。
注意, 对于无符号整数,右移必须是逻辑右移。而对于有符号整数,C 语言标准并没有明确定义应该使用哪种类型的右移,但几乎所有的编译器均采用算术右移。
参考如下示例:
代码语言:javascript复制//
//@file: main.c
//
#include <stdio.h>
#include <stdint.h>
int main()
{
int a = -1;
printf("a=0x%xn", a); //a=0xffffffff
printf("a<<1=0x%xn", a<<1); //左移,结果为 0xfffffffe
printf("a>>1=0x%xn", a>>1); //算术右移,结果为 0xffffffff
unsigned int b=1;
printf("b=0xxn", b); //b=0x00000001
printf("b<<1=0xxn", b<<1); //左移,结果为 0x00000002
printf("b>>1=0xxn", b>>1); //逻辑右移,结果为 0x00000000
}
编译输出结果:
代码语言:javascript复制gcc main.c
./a.out
a=0xffffffff
a<<1=0xfffffffe
a>>1=0xffffffff
b=0x00000001
b<<1=0x00000002
b>>1=0x00000000
参考文献
[1] 龚奕利,贺莲译.深入理解计算机系统[M].北京:机械工业出版社,2016-11.C2.1.9 C语言中的移位运算.P40-41