python运算符详解(一):https://developer.aliyun.com/article/1495699?spm=a2c6h.13148508.setting.14.163c4f0efRHJQa
(7)位运算符: & | ^ << >> ~
Python 位运算按照数据在内存中的二进制位(Bit)进行操作,它一般用于底层开发(算法设计、驱动、图像处理、单片机等),在应用层开发(Web 开发、Linux 运维等)中并不常见
存储和计算时,都用补码进行操作
var1 = 19 var2 = 15 # & 按位与 & 按位与运算符 按位与运算符&的运算规则是:只有参与&运算的两个位都为 1 时,结果才为 1,否则为 0。例如1&1为 1,0&0为 0,1&0也为 0,这和逻辑运算符&&非常类似。 计算方法,先将数字转换成二进制的补码,用补码进行按位与运算,符号位参与运算,之后将补码转换成原码显示 res = var1 & var2 """ 000 ... 10011 000 ... 01111 000 ... 00011 => 3 """ print(res)
# | 按位或 | 按位或运算符 按位或运算符|的运算规则是:两个二进制位有一个为 1 时,结果就为 1,两个都为 0 时结果才为 0。例如1|1为 1,0|0为0,1|0 为1,这和逻辑运算中的||非常类似。 res = var1 | var2 """ 000 ... 10011 000 ... 01111 000 ... 11111 """ print(res)
# ^ 按位异或 """两个值不相同=>True 反之返回False""" ^按位异或运算符 按位异或运算^的运算规则是:参与运算的两个二进制位不同时,结果为 1,相同时结果为 0。例如0^1为 1,0^0为 0,1^1为 0。 res = var1 ^ var2 """ 000 ... 10011 000 ... 01111 000 ... 11100 """ print(res)
#<< 左移 (相当于乘法)
<<左移运算符 Python 左移运算符<<用来把操作数的各个二进制位全部左移若干位,高位丢弃,低位补 0。 例如,9<<3可以转换为如下的运算: << 0000 0000 – 0000 0000 – 0000 0000 – 0000 1001 (9 在内存中的存储) 0000 0000 – 0000 0000 – 0000 0000 – 0100 1000 (72 在内存中的存储) 所以9<<3的结果为 72。 又如,(-9)<<3可以转换为如下的运算: << 1111 1111 – 1111 1111 – 1111 1111 – 1111 0111 (-9 在内存中的存储) 1111 1111 – 1111 1111 – 1111 1111 – 1011 1000 (-72 在内存中的存储) 所以(-9)<<3的结果为 -72 如果数据较小,被丢弃的高位不包含 1,那么左移 n 位相当于乘以 2 的 n 次方。 -9 * 2**3 = -72 """5乘以2的n次幂""" res = 5 << 1 # 10 res = 5 << 2 # 20 res = 5 << 3 # 40 print(res)
“”"
000 … 101 => 5
000 … 1010 => 10
000 …10100 => 20
000 .101000 => 40
“”"
#>> 右移 (相当于除法)
右移运算符
Python 右移运算符>>用来把操作数的各个二进制位全部右移若干位,低位丢弃,高位补 0 或 1。如果数据的最高位是 0,那么就补 0;如果最高位是 1,那么就补 1。
例如,9>>3可以转换为如下的运算:
0000 0000 – 0000 0000 – 0000 0000 – 0000 1001 (9 在内存中的存储)
0000 0000 – 0000 0000 – 0000 0000 – 0000 0001 (1 在内存中的存储)
所以9>>3的结果为 1。
又如,(-9)>>3可以转换为如下的运算:
1111 1111 – 1111 1111 – 1111 1111 – 1111 0111 (-9 在内存中的存储)
1111 1111 – 1111 1111 – 1111 1111 – 1111 1110 (-2 在内存中的存储)
所以(-9)>>3的结果为 -2
如果被丢弃的低位不包含 1,那么右移 n 位相当于除以 2 的 n 次方(但被移除的位中经常会包含 1)。
“”“5地板除2的n次幂”“”
res = 5 >> 1 # 2
res = 5 >> 2 # 1
res = 5 >> 3 # 0
“”"
000 … 101
000 … 010 => 2
000 … 001 => 1
000 … 000 => 0
“”"
print(res)
#~ 按位非 (针对于补码进行操作,按位取反,包含每一位)
~按位取反运算符
按位取反运算符为单目运算符(只有一个操作数),右结合性,作用是对参与运算的二进制位取反。例如1为0,~0为1,这和逻辑运算中的!非常类似。
""" -(n+1) """ # res = ~22 res = ~19 print(res) """ 原码:000 ... 10011 反码:000 ... 10011 补码:000 ... 10011 补码: 000 ... 10011 按位非: 111 ... 01100 给你补码->原码 补码:111 ... 01100 反码:100 ... 10011 原码:100 ... 10100 => -20 """ res = ~-19 print(res) """ 原码:100 ... 10011 反码:111 ... 01100 补码:111 ... 01101 补码: 111 ... 01101 按位非: 000 ... 10010 给你补码->原码 (因为是正数 ,原反补相同) 000 ... 10010 => 18 """
总结:
个别运算符:
运算符优先级最高的: **
运算符优先级最低的: =
()可以提升优先级
一元运算符 > 二元运算符 (优先级)
一元运算符 : 同一时间,操作一个值 ~ -
二元运算符 : 同一时间,操作两个值 + - * / …
同一种类运算符:
算数运算符 : 乘除 > 加减
逻辑运算符 : () > not > and > or
位运算符 : ( << >> ) > & > ^ > |
整体排序:
算数运算符 > 位运算符 > 比较运算符 > 身份运算符 > 成员运算符 > 逻辑运算符 >赋值
赋值运算符用来做收尾
算位比身成逻
res = 5+5 << 6 // 3 is 40 and False
Python 3.8(或更高)下:
出现报错
SyntaxWarning: "is" with a literal. Did you mean "=="? 1 解决方法: 将对应语句中is/is not用== 和 != 代替
原因:
从 python 3.8 开始,使用 is 和 is not 运算符时,会抛出 SyntaxWarning 语句警告信息
“”"
res = 10 << 2 is 40 and False
res = 40 is 40 and False
res = True and False
res = False
“”"
print(res)
优先级不是每个人都要熟记于心,为了便于新人理解,可用括号提升下优先级,这样就看起来比较直白
res = (5+5) << (6//3) is 40 and False