3.1.5 位运算符
位运算符是把数字看作二进制数来进行计算的,因此需要先将要执行运算的数据转换为二进制,然后才能执行运算。Python中的位运算符有按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、左移位(<<)和右移位(>>)运算符。
说明
整型数据在内存中以二进制的形式表示,如整型变量7的32位二进制表示00000000 00000000 00000000 00000111,其中,左边最高位是符号位,最高位为0表示正数,若为1则表示负数。负数采用补码表示,如−7的32位二进制表示为11111111 11111111 11111111 11111001。
1.“按位与”运算
“按位与”运算的运算符为“&”,它的运算法则是,两个操作数的二进制表示,只有对应位都为1,结果位才为1,否则为0。如果两个操作数的精度不同,则结果的精度与精度高的操作数相同,如图3.7所示。
图3.7 12&8的运算过程
2.“按位或”运算
“按位或”运算的运算符为“|”,它的运算法则是,两个操作数的二进制表示,只有对应位都为0,结果位才为0,否则为1。如果两个操作数的精度不同,则结果的精度与精度高的操作数相同,如图3.8所示。
3.“按位异或”运算
“按位异或”运算的运算符是“^”,它的运算法则是,当两个操作数的二进制表示相同(同时为0或同时为1)时,结果为0,否则为1。如果两个操作数的精度不同,则结果数的精度与精度高的操作数相同,如图3.9所示。
4.“按位取反”运算
“按位取反”运算也称“按位非”运算,运算符为“~”。“按位取反”运算就是将操作数对应二进制中的1修改为0,0修改为1,如图3.10所示。
图3.8 4|8的运算过程
图3.9 31^22的运算过程
图3.10 ~123的运算过程
在Python中使用print()函数输出图3.7~图3.10的运算结果,代码如下:
01 print("12&8 = "+str(12&8)) # 按位与计算整数的结果 02 print("4|8 = "+str(4|8)) # 按位或计算整数的结果 03 print("31^22 = "+str(31^22)) # 按位异或计算整数的结果 04 print("~123 = "+str(~123)) # 按位取反计算整数的结果
运算结果如图3.11所示。
图3.11 图3.7~图3.10的运算结果
5.“左移位”运算
“左移位”运算符为“<<”,它的运算法则是将一个二进制操作数向左移动指定的位数,左边(高位端)溢出的位被丢弃,右边(低位端)的空位用0补充。左移位运算相当于乘以2n。
例如,int类型数据48对应的二进制数为00110000:将其左移1位,根据左移位运算符的运算规则可以得出(00110000<<1)=01100000,所以转换为十进制数就是96(48×2);将其左移2位,根据左移位运算符的运算规则可以得出(00110000<<2)=11000000,所以转换为十进制数就是192(48×22)。其执行过程如图3.12所示。
6.“右移位”运算
“右移位”的运算符为“>>”,它的运算法则是将一个二进制操作数向右移动指定的位数,右边(低位端)溢出的位被丢弃,而当填充左边(高位端)的空位时:如果最高位是0(正数),则左侧空位填入0;如果最高位是1(负数),则左侧空位填入1。右移位运算相当于除以2n。
正数48右移1位的运算过程如图3.13所示。
图3.12 左移位运算
图3.13 正数的右移位运算过程
负数−80右移2位的运算过程如图3.14所示。
图3.14 负数的右移位运算过程
说明
由于移位运算的速度很快,当程序中遇到表达式乘以或除以2n的情况时,一般采用移位运算来代替。
【例3.4】使用位移运算符对密码进行加密。(实例位置:资源包\TM\sl\03\04)
在IDLE中创建一个名称为encryption.py的文件,然后在该文件中定义两个变量:一个用于保存密码,另一个用于保存加密参数。接着应用左移位运算符实现加密,并输出结果。最后应用右移位运算符实现解密,并输出结果,代码如下:
01 password = 87654321 # 密码 02 key = 7 # 加密参数 03 print("\n原密码:",password) # 输出原密码 04 password = password << key # 将原密码左移,生成新的数字 05 print("\n加密后:",password) # 输出加密后的密码 06 password = password >> key # 将新密码右移,还原密码 07 print("\n解密后:",password) # 输出解密后的密码
运行上述代码,将显示如图3.15所示的运行结果。
图3.15 对密码进行加密和解密的结果