一、位(bit)运算符
运算符 | 类型 | 解释 |
---|---|---|
& | 双目运算符 | 按位与,相同位的两个数字都为1,则为1;若有一个不为1,则为0。 |
| | 双目运算符 | 按位或,相同位只要一个为1即为1 |
~ | 单目运算符 | 按位取非,0,1互换,包括符号位 |
说明:任何数跟0做位与,结果为0,任何数跟1做位与,保持原值
下表模拟C = A & B
,即将A与B的每一位都执行按位与操作将结果赋值给C
数字 | 2进制 | 16进制 |
---|---|---|
A | 001011010 | 0x5A |
B | 011100111 | 0xE7 |
C | 011111111 | 0xFF |
说明:内存中的二进制以补码的方式存在,高位有一位符号位标志。正数0,负数为1
二、移位运算符
1、功能:将二进制数整体向左边或者向右边移动N个位置
运算符 | 类型 | 规则 | 数学意义 |
---|---|---|---|
<< | 双目运算符 | 左移:按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。 | 在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方。 |
>> | 双目运算符 | 右移:按二进制形式把所有的数字向右移动对应位移位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1 | 右移一位相当于除2,右移n位相当于除以2的n次方。 |
左移:A<<B
语义:将A左移B个位置
例如3 << 2,则是将数字3左移2位
首先把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011,
然后把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,最后在低位(右侧)的两个空位补零。
则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1100,
则转换为十进制是12。
右移:A>>B
语义:将A右移B个位置
例如11 >> 2,则是将数字11右移2位
11的二进制形式为:0000 0000 0000 0000 0000 0000 0000 1011,
然后把低位的最后两个数字移出,因为该数字是正数,所以在高位补零。
则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 0010。
转换为十进制是2。
移位运算符特点
1.向左移动后右边空出来的数据用0来填充
0x5a << 2 = 01011010 << 2 = 01101000
2.无符号类型数字右移时左边空出来的数据用0来填充
unsigned char a = 0xa5; a >> 2 = 10100101 >> 2 = 00101001
3.有符号类型数字右移时左边空出来的数据用符号位来填充
char a = 0xa5; a >> 2 = 10100101 >> 2 = 11101001
4.移位运算符不会修改变量本身的值
5.只要将来有2的多少次方处理的代码,建议用移位操作
例如:
3*4; //垃圾代码,CPU运行*,/的效率极低
3<<2; //高薪代码,CPU运行移位操作效率极高
12/4; //不推荐
12>>2; //推荐
位运算符和移位运算符结合——清0和置1
实际开发常见的场景:位清0和位置1
(1)清0公式:
内容 | 公式 |
---|---|
1.将某个数据A的第n位清0,其它位保持不变: | A &= ~(0x1 << n); |
2.将某个数据A从第n位开始,连续两个bit位清0,其它位保持不变: | A &= ~(0x3 << n); |
3.将某个数据A从第n位开始,连续三个bit位清0,其它位保持不变: | A &= ~(0x7 << n); |
4.将某个数据A从第n位开始,连续四个bit位清0,其它位保持不变: | A &= ~(0xF << n); |
5.将某个数据A从第n位开始,连续五个bit位清0,其它位保持不变: | A &= ~(0x1F << n); |
6.将某个数据A从第n位开始,连续六个bit位清0,其它位保持不变: | A &= ~(0x3F << n); |
7.将某个数据A从第n位开始,连续七个bit位清0,其它位保持不变: | A &= ~(0x7F << n); |
8.将某个数据A从第n位开始,连续八个bit位清0,其它位保持不变: | A &= ~(0xFF << n); |
内容 | 公式 |
---|---|
将某个数据A的第n位置1,其它位保持不变: | A |= (0x1 << n); |
2.将某个数据A从第n位开始,连续两个bit位置1,其它位保持不变: | A |= (0x3 << n); |
3.将某个数据A从第n位开始,连续三个bit位置1,其它位保持不变: | A |= (0x7 << n); |
4.将某个数据A从第n位开始,连续四个bit位置1,其它位保持不变: | A |= (0xF << n); |
5.将某个数据A从第n位开始,连续五个bit位置1,其它位保持不变: | A |= (0x1F << n); |
6.将某个数据A从第n位开始,连续六个bit位置1,其它位保持不变: | A |= (0x3F << n); |
7.将某个数据A从第n位开始,连续七个bit位置1,其它位保持不变: | A |= (0x7F << n); |
8.将某个数据A从第n位开始,连续八个bit位置1,其它位保持不变: | A |= (0xFF << n); |