採用書籍Python核心編程(第二版),人民郵電出版社,2008年7月第1版。本書以Python2.5爲主,但筆記主要以Python3.6爲主。
一、Python位運算操作符
Python支持標準位運算,位運算操作符只能用於整數。操作符如下:
操作符 | 意義 | 舉例 | 操作符 | 意義 | 舉例 |
---|---|---|---|---|---|
~ | 按位取反 | ~5 | & | 按位與 | 5&6 |
| | 按位或 | 5|6 | ^ | 按位異或 | 5^6 |
<< | 左移m位 | 5<<1 | >> | 右移 | 6>>1 |
二、原碼反碼補碼
原碼反碼補碼的一般說法:
- 原碼:原碼是二進制數字的一種簡單的表示法。二進制首位爲符號位,1代表負,0代表正。
- 反碼:反碼可由原碼得到。如果是正數,反碼與原碼相同;如果是負數,反碼是其原碼(符號位除外)各位取反而得到的。
- 補碼:補碼可由原碼得到。如果是正數,補碼與原碼相同;如果是負數,補碼是對其原碼(除符號位外)各位取反,並在末位加1而得到的(有進位則進位,但不改變符號位)。
但是爲什麼會有原碼、反碼、補碼呢?簡單來說,原碼是爲了方便人計算,補碼是方便計算機計算,而反碼是認爲提出的一箇中間橋樑。參考這篇文章:原碼、反碼和補碼,總結幾點:
- 計算機裏面,只有加法器,沒有減法器,所有的減法運算,都必須用加法進行。
- 用補數代替原數,可把減法轉變爲加法。出現的進位就是模,此時的進位,就應該忽略不計。
- 二進制下,有多少位數參加運算,模就是在 1 的後面加上多少個 0。
- 補碼就是按照這個要求來定義的:正數不變,負數即用模減去絕對值。
- 舉例:以10爲模,6的補碼是6,-6的補碼是4。9-6=9+(-6)=9+(10-6)=9+4=13,13%10=3,結果爲3,完全正確!
- 舉例:8位二進制的模是100000000,3的補碼是00000011,-3的補碼是11111100(100000000-00000011)。
以 8 位二進制舉幾個簡單例子:
整數 | 原碼 | 反碼 | 補碼 |
---|---|---|---|
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 |
11111111 | 10000000 | 10000001 |
表格有兩個錯誤表示:+0和-0,但是給 0 加正負號根本沒有意義。我們不會討論 +0 或 -0 的原碼反碼和補碼,因爲這二者本來就是 0。所以,0(包括+0、-0)的原碼反碼和補碼都是00000000。
數字在計算機中用二進制補碼形式表示,補碼10000000表示的不是 -0,而是-128。用參考資料中的“模理論”來說明,-128的補碼的計算方法:模的二進制-絕對值的二進制(100000000-10000000)=10000000。
三、Python位運算
數字在計算機中是以補碼保存的,所以用Python位運算作用在補碼上,每一位都參與運算:
- 按位取反~:按位取反後得到二進制表示,把該二進制看成一個新的補碼,返回該補碼對應的數字結果。
- 按位與&,或|,異或^:同取反~
- 左移<<和右移>>:左移和右移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】整數的二進制用二進制補碼形式表示,那浮點數呢?
- 答:浮點數當然也用二進制補碼形式表示啦。可以參考另一篇博客 由Python浮點數溢出問題到二進制
參考資料:
推薦資料: