python中的原碼反碼和補(bǔ)碼
原碼反碼和補(bǔ)碼的概念
- 原碼:原碼是二進(jìn)制數(shù)字的一種簡(jiǎn)單的表示法。二進(jìn)制首位為符號(hào)位,1代表負(fù),0代表正。
- 反碼:反碼可由原碼得到。如果是正數(shù),反碼與原碼相同;如果是負(fù)數(shù),反碼是其原碼(符號(hào)位除外)各位取反而得到的。
- 補(bǔ)碼:補(bǔ)碼可由原碼得到。如果是正數(shù),補(bǔ)碼與原碼相同;如果是負(fù)數(shù),補(bǔ)碼是對(duì)其原碼(除符號(hào)位外)各位取反,并在末位加1而得到的(有進(jìn)位則進(jìn)位,但不改變符號(hào)位)。
更詳細(xì)的介紹可參考這篇文章
原碼反碼和補(bǔ)碼的示例
如下以8位二進(jìn)制為例:
| 真值 | 原碼 | 反碼 | 補(bǔ)碼 | 備注 |
|---|---|---|---|---|
| 2^7-1=127 | 0 1111111 | 0 1111111 | 0 1111111 | 正數(shù)的原碼反碼補(bǔ)碼相同 |
| + 7 | 0 0000111 | 0 0000111 | 0 0000111 | 正數(shù)的原碼反碼補(bǔ)碼相同 |
| + 1 | 0 0000001 | 0 0000001 | 0 0000001 | 正數(shù)的原碼反碼補(bǔ)碼相同 |
| 0 | 0 0000000 | 0 0000000 | 0 0000000 | 正數(shù)的原碼反碼補(bǔ)碼相同 |
| - 1 | 1 0000001 | 1 1111110 | 1 1111111 | 負(fù)數(shù)的補(bǔ)碼是符號(hào)位不變其余取反加 1 |
| - 7 | 1 0000111 | 1 1111000 | 1 1111001 | 負(fù)數(shù)的補(bǔ)碼是符號(hào)位不變其余取反加 1 |
| ?(2^7?1)=?127 | 1 1111111 | 1 0000000 | 1 0000001 | 負(fù)數(shù)的補(bǔ)碼是符號(hào)位不變其余取反加 1 |
特殊地?cái)?shù)字在計(jì)算機(jī)中用二進(jìn)制補(bǔ)碼形式表示,補(bǔ)碼10000000表示的不是 -0,而是-128
python中的原碼反碼及補(bǔ)碼
一般來講,整形數(shù)在內(nèi)存中是以 補(bǔ)碼 的形式存放的,輸出的時(shí)候同樣也是按照 補(bǔ)碼 輸出的。
但是在 Python 中,情況是這樣的:
- 整形是以 補(bǔ)碼 形式存放的,輸出的時(shí)候是按照 二進(jìn)制 表示輸出的;
- 對(duì)于 bin(x)(x為 十進(jìn)制負(fù)數(shù)),輸出的是它的原碼的二進(jìn)制表示加上一個(gè)負(fù)號(hào),方便查看
- 對(duì)于 bin(x)(x 為 十六進(jìn)制負(fù)數(shù)),輸出的是對(duì)應(yīng)的二進(jìn)制表示。
所以為了獲得十進(jìn)制負(fù)數(shù)的補(bǔ)碼,我們需要手動(dòng)將其和 0xffffffff 進(jìn)行與操作,得到一個(gè)十六進(jìn)制數(shù),再交給 bin() 轉(zhuǎn)化,這時(shí)內(nèi)存中得到的才是你想要的補(bǔ)碼。
a = bin(-3)
print(a)
a = bin(3)
print(a)
b = bin(-3 & 0xffffffff)
print(b)
c = bin(0xfffffffd)
print(c)
# 輸出
# -0b11
# 0b11
# 0b11111111111111111111111111111101
# 0b11111111111111111111111111111101