在计算机中都是形如 0101 的编码,为了简化计算机的设计,cpu只能进行加法运算,通过补码的形式进行减法运算。

而对于乘法和除法和一些其它的运算,是可以转为位运算的,这就是位运算存在的意义。

求原码反码补码的规则:

  • 正数的原码反码补码为其本身
  • 负数的原码最高位补1,负数反码为原码取反,负数的补码为反码加1

Python中位运算符和operator的对应如下;

位运算符operator方法说明
&operator.add_(a,b)按位与,如果参与运算的两个值都为1则结果为1,否则为0
|operator.or_(a,b)按位或,只要参与运算的两个值有一个为1则结果为1
^operator.xor(a,b)按位异或,两个值同者为0,异者为1,即相同为0,不同为1
~operator.invert(a)按位取反,0变为1,1变为0
<<operator.lshift(a,b)右移,移动一位相当于/2
>>operator.rshift(a,b)左移,高位舍掉,低位补0.移动一位相当于*2

下面举例说明Pyhton的位运算符的使用方法。

1)按位与

#!/usr/bin/python
# coding=utf-8
import operator

a=9; b=13
c=a & b
print(c) #输出9

print(operator.and_(a, b)) #输出9
输出:
9
9

按位与的原则是两个值都为1结果为1,否则为0。

解释一下为什么结果是9:

9转为二进制编码为     0 0 0 0 1 0 0 1  

13转为二进制编码为   0 0 0 0 1 1 0 1

那么第一位 1和1结果为1,第二位0和1结果为0,第三位0和0结果为0, 第四位1和1结果为1

所以,结果为 1 0 0 1,转为10进制为 9 ,其中operator.and_(a, b)是Python支持库operator的写法。

2)按位或

#!/usr/bin/python
# coding=utf-8
import operator

a=9; b=13
c=a | b
print(c) #输出13

print(operator.or_(a, b)) #输出13
输出:
13
13

按位或的原则是只要有一个为1结果为1,

还是按照上面的说法解释结果为什么是13.

9转为二进制编码为     0 0 0 0 1 0 0 1  

13转为二进制编码为   0 0 0 0 1 1 0 1

那么第一位 1和1结果为1,第二位0和1结果为1,第三位0和0结果为0, 第四位1和1结果为1

所以,结果为 1 1 0 1,转为10进制为 13 ,其中operator.or_(a, b)是Python支持库operator的写法。

3)按位异或

#!/usr/bin/python
# coding=utf-8
import operator

a=9; b=13
c=a ^ b
print(c) #输出4

print(operator.xor(a, b)) #输出4
输出:
4
4

按位或的原则是两个数,同者为0,异者为1,

还是按照上面的说法解释结果为什么是13.

9转为二进制编码为    0 0 0 0 1 0 0 1  

13转为二进制编码为  0 0 0 0 1 1 0 1

那么第一位 1和1结果为0,第二位0和1结果为1,第三位0和0结果为0, 第四位1和1结果为0

所以,结果为 0 1 0 0,转为10进制为 4,其中operator.xor(a, b)是Python支持库operator的写法。

4)按位取反

#!/usr/bin/python
# coding=utf-8
import operator

a=9
c=~a
print(c) #输出-10

print(operator.invert(a)) #输出-10
输出:
-10
-10

解释一下结果为什么是-10。

9的二进制编码为:0 0 0 0 1 0 0 1

按位取反:           1 1 1 1 0 1 1 0

按位取反的值为补码,且是负数,我们要求该补码的原码,

取反码减1为:      1 1 1 1 0 1 0 1 

转原码,符号位不变,其他取反,

结果为:              1 0 0 0 1 0 1 0 

转为10进制,所以最后结果为-10.

5)右移

#!/usr/bin/python
# coding=utf-8
import operator

a=9
c=a>>1 # 右移1位
print(c) #输出4

print(operator.rshift(a, 1)) #输出4

输出:

4
4

右移等于缩小/2

9转为二进制编码为    0 0 0 0 1 0 0 1  

右移一位变为:         0 0 0 0  0 1 0 0
所以转为10进制为 4

6)左移

#!/usr/bin/python
# coding=utf-8
import operator

a=9
c=a<<1 # 左移1位
print(c) #输出18

print(operator.lshift(a, 1)) #输出18
输出:
18
18

左移等于放大*2

9转为二进制编码为    0 0 0 0  1 0 0 1  

右移一位变为:         0 0 0 1  0 1 0 0
所以转为10进制为 18