C语言提供了6种位运算符:&(与运算符,按位与),|(或运算符,按位或),^(异或运算符,按位异或),~(非运算符,按位取反),<<(左移运算符,向左移位,低位补0),>>(右移运算符)
左移运算
1.左移运算(向左移位,低位补0) 无需考虑运算数是 有符号数 还是 无符号数,均是在低位补0。
2.左移运算后,若数值超出数据类型的取值范围 (溢出),就会发生数据截断 (高位丢失,保留低位)。
- 截断后,数据的值,甚至符号位都可能会发生改变(有符号数,左移后可能会由正数变为负数(如图①),也可能会由负数变为正数(如图②))
3. 针对数据溢出截断问题,可以将短数据类型 转成 长数据类型 (位数扩展)。如8位的char 转成 16位的short、32位的int、64位的long
-
无符号数的位数扩展,左边补0
-
有符号数的位数扩展,左边补符号位 (符号位是0就补0,符号位是1就补1)
-
注意:数据进行位数扩展后,数值不会发生改变。
b1发生溢出,截取低8位1111 1100 ; b2进行了位数扩展,没有发生溢出。
4.左移运算中,a<<1 相当于 a乘以
2
1
2^{1}
21 ; a<
右移运算需要考虑数值是有符号数还是无符号数两种情况,所以对有符号数和无符号数不理解的先去看看 c语言中的有符号数(signed)和无符号数(unsigned)
1.右移运算分 无符号右移(逻辑右移) 和 有符号右移(算数右移)
-
逻辑右移:高位补0
-
算术右移:高位补符号位 (符号位是0就补0,符号位是1就补1)
2.因为右移运算是向下取整,而整除运算是向0方向取整。所以a>>1 相当于 a除以 2 1 2^{1} 21 ,这个结论只有正数适用,而负数不适用。
3.c语言中逻辑右移和算术右移都用 >> 表示。 java中>>表示算术右移,>>>表示逻辑右移 (注意:java没有<<<运算符)



