由Python位运算到原码反码补码

采用书籍Python核心编程(第二版),人民邮电出版社,2008年7月第1版。本书以Python2.5为主,但笔记主要以Python3.6为主。

一、Python位运算操作符

Python支持标准位运算,位运算操作符只能用于整数。操作符如下:

操作符 意义 举例 操作符 意义 举例
~ 按位取反 ~5 & 按位与 5&6
| 按位或 5|6 ^ 按位异或 5^6
<< 左移m位 5<<1 >> 右移 6>>1

二、原码反码补码

原码反码补码的一般说法:

  1. 原码:原码是二进制数字的一种简单的表示法。二进制首位为符号位,1代表负,0代表正。
  2. 反码:反码可由原码得到。如果是正数,反码与原码相同;如果是负数,反码是其原码(符号位除外)各位取反而得到的。
  3. 补码:补码可由原码得到。如果是正数,补码与原码相同;如果是负数,补码是对其原码(除符号位外)各位取反,并在末位加1而得到的(有进位则进位,但不改变符号位)。

但是为什么会有原码、反码、补码呢?简单来说,原码是为了方便人计算,补码是方便计算机计算,而反码是认为提出的一个中间桥梁。参考这篇文章:原码、反码和补码,总结几点:

  1. 计算机里面,只有加法器,没有减法器,所有的减法运算,都必须用加法进行。
  2. 用补数代替原数,可把减法转变为加法。出现的进位就是模,此时的进位,就应该忽略不计。
  3. 二进制下,有多少位数参加运算,模就是在 1 的后面加上多少个 0。
  4. 补码就是按照这个要求来定义的:正数不变,负数即用模减去绝对值。
  5. 举例:以10为模,6的补码是6,-6的补码是4。9-6=9+(-6)=9+(10-6)=9+4=13,13%10=3,结果为3,完全正确!
  6. 举例:8位二进制的模是100000000,3的补码是00000011,-3的补码是11111100(100000000-00000011)。

以 8 位二进制举几个简单例子:

整数 原码 反码 补码
271=127 01111111 01111111 01111111
+7 00000111 00000111 00000111
+1 00000001 00000001 00000001
+0(同0) 00000000(同0) 00000000(同0) 00000000(同0)
0 00000000 00000000 00000000
-0(错误) 10000000(错误) 11111111(错误) 10000000(错误)
-1 10000001 11111110 11111111
-7 10000111 11111000 11111001
(271)=127 11111111 10000000 10000001

表格有两个错误表示:+0和-0,但是给 0 加正负号根本没有意义。我们不会讨论 +0 或 -0 的原码反码和补码,因为这二者本来就是 0。所以,0(包括+0、-0)的原码反码和补码都是00000000

数字在计算机中用二进制补码形式表示,补码10000000表示的不是 -0,而是-128。用参考资料中的“模理论”来说明,-128的补码的计算方法:模的二进制-绝对值的二进制(100000000-10000000)=10000000。

三、Python位运算

数字在计算机中是以补码保存的,所以用Python位运算作用在补码上,每一位都参与运算:

  1. 按位取反~:按位取反后得到二进制表示,把该二进制看成一个新的补码,返回该补码对应的数字结果。
  2. 按位与&,或|,异或^:同取反~
  3. 左移<<和右移>>:左移和右移N位等同于无溢出检查(忽略溢出)的N次幂运算2**N。对长整型来说,位操作符使用一种修改的二进制补码形式,使得符号位可以无限向左扩展。也就是说,向左移位不会溢出。

Python位运算举例:

>>> ~7 # 解释:7的补码是00000111 对补码取反得到11111000 该补码对应的整数为-8
-8
>>> ~-7 # 解释:-7的补码是11111001 对补码取反得到00000110 该补码对应的整数为6
6
>>> 6 & 5 
4
>>> 5 & 4
4
>>> 7 << 2
28
>>> 28 << 2
112

【补充1】原码到反码再到补码的计算很简单,但是补码如何变回到原码呢?

  • 答:补码的补码就是原码啊。如果补码首位为0,表示该数字为正数,原码反码都与补码相同。如果补码首位为1,表示该数字为负数,对补码再进行一次取反和末位加1操作即可得到原码。得到原码,即可得到该数字。

【补充2】整数的二进制用二进制补码形式表示,那浮点数呢?


参考资料:

  1. 原码、反码和补码
  2. 原码、反码、补码的产生、应用以及优缺点有哪些?

推荐资料:

  1. 位运算简介及实用技巧(一):基础篇
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章