Python从入门到精通(第3版)
上QQ阅读APP看书,第一时间看更新

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 对密码进行加密和解密的结果