1. 位运算符分类
运算符 | 描述 | 功能 | 运算规则 |
& | 按位与运算符 | 将参与运算的两数各对应的二进位相与 | 参与运算的两个数,同时为1时,值才为1,否则为0 |
| | 按位或运算符 | 将参与运算的两数各对应的二进位相或 | 参与运算的两个数,只要有一个为1,其值就为1 |
^ | 按位异运算符 | 将参与运算的两数各对应的二进位相异 | 参加运算的两个数,如果两个相应位为“异”(值不同),则该位结果为1,否则为0 |
<< | 左移运算符 | 把"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0 | a = a << 2 将a的二进制位左移2位,右补0 |
>> | 右移运算符 | 把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数。 | a = a >> 2 将a的二进制位右移2位,左边补0 或补1,看被移动的数是正数还是负数 |
他们都属于双目运算符
2. 位运算符事例
2.1 & (按位与运算符)
运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;
即,参与运算的两位数,同时为1时,结果才是1,否则为0
举个栗子:
int a = 60 /* 60 转二进制是 0 0 1 1 1 1 0 0 */
int b = 13 /* 13 转二进制是 0 0 0 0 1 1 0 1 */
根据 “&” 运算符,运算规则进行运算
0 0 1 1 1 1 0 0
0 0 0 0 1 1 0 1
---------------
0 0 0 0 1 1 0 0
得到的二进制是 0 0 0 0 1 1 0 0 ,然后将该二进制转换成十进制,就是12
即 a & b =12
小知识:"&" 按位与运算符逻辑跟 "&&" 并运算符逻辑相似,就是条件都满足时,结果才为True
2.2 | (按位或运算符)
运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1;
即,参与运算的两个对象,只要有一个为1,其值就为1
举个栗子:
int a = 60 /* 60 转二进制是 0 0 1 1 1 1 0 0 */
int b = 13 /* 13 转二进制是 0 0 0 0 1 1 0 1 */
根据 “|” 运算符,运算规则进行运算
0 0 1 1 1 1 0 0
0 0 0 0 1 1 0 1
---------------
0 0 1 1 1 1 0 1
得到的二进制是 0 0 1 1 1 1 0 1 ,然后将该二进制转换成十进制,就是61
即 a | b = 61
小知识:"|" 按位或运算符逻辑跟 "||" 或运算符逻辑相似,只要满足其中一个条件时,结果就为True
2.3 ^ (按位异运算符)
运算规则:0^0=0; 0^1=1; 1^0=1; 1^1=0;
即,参加运算的两个数,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
举个栗子:
int a = 60 /* 60 转二进制是 0 0 1 1 1 1 0 0 */
int b = 13 /* 13 转二进制是 0 0 0 0 1 1 0 1 */
根据 “^” 运算符,运算规则进行运算
0 0 1 1 1 1 0 0
0 0 0 0 1 1 0 1
---------------
0 0 1 1 0 0 0 1
得到的二进制是 0 0 1 1 0 0 0 1 ,然后将该二进制转换成十进制,就是49
即 a ^ b = 49
2.4 << (左移运算符)
运算规则: a = a << 2 将a的二进制位左移2位,右补0
举个栗子:
int a = 60 /* 60 转二进制是 0 0 1 1 1 1 0 0 */
将 a 进行左移 2 位,即 int c = a << 2
然后,根据 “<<” 运算符,运算规则进行运算。
左移1位后a = a * 2;
若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。
0 0 1 1 1 1 0 0
-----左移 2 位-------
1 1 1 1 0 0 0 0
---左移1位----
60 * 2
----左移2位-----
60 * 4 = 240 /* 1 1 1 1 0 0 0 0 */
得到的二进制是 1 1 1 1 0 0 0 0 ,然后将该二进制转换成十进制,就是240
即 int c = a << 2 ,c = 240
如何理解左移舍弃的高位不包含1,这句话。
举个栗子 ,例如,78<<2 。由上得如,左移2位,相当于78*4 =312
1.接来下进行验证,78的二进制 0 1 0 0 1 1 1 0
0 1 0 0 1 1 1 0
0 1 0 0 1 1 1 0 0 0
--------------------------
1 0 0 1 1 1 0 0 0 二进制转10进制就是312。由于高位有1,进行保留。
左移时2位中高位包含1,进行保留,这样计算的结果才是准确的。如果左移出高位都是0,直接都舍弃掉。
再举个栗子,如十进制的54 左移2位。二进制是 0 0 1 1 0 1 1 0
0 0 1 1 0 1 1 0
0 0 1 1 0 1 1 0 0 0
-------------------------
1 1 0 1 1 0 0 0 二进制转换成10进制就是216。由于高位无1,进行舍弃
如上是个人理解。如有错误请多多指教。
2.5 >> (右移运算符)
运算规则:a = a >> 2 将a的二进制位右移2位。左边补0 或补1,看被移动的数是正数还是负数。正数左补0,负数左补1,右边丢弃。
举个栗子:
int a = 60 /* 60 转二进制是 0 0 1 1 1 1 0 0 */
将 a 进行右移 2 位,即 int c = a >> 2
然后,根据 “>>” 运算符,运算规则进行运算。
操作数每右移一位,相当于该数除以2。
0 0 1 1 1 1 0 0
-----右移 2 位-------
0 0 0 0 1 1 1 1
-----右移1位-------
60 / 2
-----右移2位--------
60 / 4 = 15 /* 0 0 0 0 1 1 1 1 */
根据正数左补0,负数左补1,得到的二进制是 0 0 0 0 1 1 1 1 ,然后将该二进制转换成十进制,就是15
即 int c = a >> 2 ,c = 15
参考资料: