什么是位运算
位运算就是把数字当成二进制来进行计算, 位运算有六种:&(与), |(或), ^(异或), ~(非), <<(左移),>>(右移)
&(与)
& 运算规则: 两个位都为 1, 结果为 1, 否则为 0
- # &(与)
- a = 3
- b = 9
- print(a & b)
- # a----0101
- # b----1001
- # a&b--0001
- # a&b=1
- |(或)
| 运算规则: 两个位至少有一个为 1, 结果为 1, 否则为 0
- # |(或)
- a = 3
- b = 9
- print(a | b)
- # a----0101
- # b----1001
- # a|b--1101
- # a|b=11
- ^(异或)
^ 运算规则: 两个位不同, 结果为 1, 否则为 0
- # ^(异或)
- a = 3
- b = 9
- print(a ^ b)
- # a----0101
- # b----1001
- # a^b--1100
- # a^b=10
- ~(非)
~ 运算规则: 对所有位取反, 1 变成 0,0 变成 1
a = 5 print(~a)
猜猜结果是多少? 是不是以为是 2, 哈哈哈
看一下打印结果
-6
what? 检查下计算过程
- # a----101
- # ~a--010
- # ~a=2
按照运算规则, 没错啊
这是为什么呢? 其实, 计算机中是以补码的形式来进行计算的
对于正数:
原码 = 反码 = 补码
对于负数:
反码 = 原码的符号位不变, 其余位取反;
补码 = 反码 + 1
使用 sys.getsizeof 可以查看对象在内存空间占用的大小
- import sys
- a = 5
- print(sys.getsizeof(a)) # 28
说明 a 在内存中占的位数是 28
现在我们来一步一步等推算~ a
a 的二进制形式
0000 00000000 00000000 00000101
由于运算是以补码的形式进行, 因此要将原码转化成补码, 由于 a 为整数, 因此其补码就等于原码
- # a 的补码
- 0000 00000000 00000000 00000101
对 a 的补码进行~ 运算, 结果为
- # 结果的补码
- 1111 11111111 11111111 11111010
到这里要注意了, 计算机运算的时候是以补码的形式, 但是显示到终端上还是以原码的形式, 因此我们要把结果再转化回原码
由于结果为负数 (符号为 1), 先把补码转化成反码, 反码 = 补码 - 1
- # 结果的反码
- 1111 11111111 11111111 11111001
再计算结果的原码
- # 结果的原码
- 1000 00000000 00000000 00000110
再把结果的二进制转化成十进制形式, 符号为 1 说明是负数,-(4+2)= -6, 因此结果为 - 6
上面的计算过程只是让我们对计算机如何进行位运算有一个认识, 实际上对于任意数 a,~a = -(a+1), 根本不用手工转化成二进制计算
<<(左移位)
<< 的规则: 运算数的各二进位全部左移若干位, 由 << 右边的数字指定了移动的位数, 高位丢弃, 低位补 0.
- a = 9
- print(a << 2) # 36
对于整数 a,a<<n 等效于 a*2**n, 也就是说移位运算可以替代乘法运算
>>(右移位)
'>>'的规则: 运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数
- a = 9
- print(a>> 2) # 2
对于整数 a,a<<n 等效于 int(a/2**n), 向右移位可以代替除法运算
来源: http://www.bubuko.com/infodetail-3005646.html