標籤:
按位取反再加一(補碼)
按位取反再加1是一個互逆運算。a取反加一,再取反加一,還等於a
------------------------------------
在電腦中,減法可以用加法來代替,用的就是補碼。說道補碼,就得說道“模”這個概念。假如我有一個電腦,它只有四個bit,這四個bit所能表示的值的範圍用二進位表示是0000到1111,即從0到15。這樣,這個電腦就只能表示這16個數,別的東西它就無法表示了。這個16就是這個電腦的“模”,在這個電腦上進行的計算只能在“模”的表示範圍之內。
如果我們要計算5-3的值,我們既可以用5減去3,也可以用5加上13。這是為什麼呢?這就像我們的鐘錶,它從1點走到12點之後,又回到了1點。我們的電腦也是,從0走到15之後,再往下走就又回到了0,就像我們轉了一個圈一樣。我們從5這個位置往回退3個格,就完成了5-3這個計算。我們也可以從5這個位置往前走,一直走到15,這時我們走了10個格,然後我們繼續往前走,走到0,然後到1,然後就走到了2。這樣,我們往前走了13個格之後,也到了2這個位置。所以說,在我們這個電腦中,減3和加13是一樣的。而3+13=16,我們說在模16的系統下,3和13是互補的。
這樣,我們計算5-3就可以換成5+13。3的二進位表示為0011,5的二進位表示為0101。這樣,0101-0011就可以表示為0101+(-0011)。我們在電腦中都是把負數用其補碼錶示,-0011的補碼就是10000-0011(即16-3,也就是13)。10000-0011=1+1111-0011=1+(1111-0011)=1+1100=1101。我們總說補碼是“按位取反再加一”,看了上面這個式子相信大家就會明白了,其實就是把10000-0011換成了1111-0011再加1的形式。然後,0101-0011就換成了0101+1101,它們計算出來的結果為10010。由於我們的電腦只有四個bit,所以結果為0010。即,在模16的電腦中,5-3=5+13=2。
------------------------------------
先看正碼錶示,設N=4, -1 = 1001; -2 = 1010, -1 > -2, 但是 1001 < 1010,兩種映射的編碼的序性不一致
反碼呢,-1=1110, -2 = 1101, Ok,序性正確了,
然而,這裡有一個問題,就是正數與負數之間,有一個1的縫隙。-1=1110, 1=0001,從迴圈編碼的角度,這兩個編碼相差3:1110->1111->0000->0001。
因為正零和負零是兩個數,導致兩個數系的斷裂。怎麼辦?讓負數整體往正數靠攏,邁進一步(+1),負1沒有了。
這就是求補的過程了。反碼再加1。
我想,當初寫出電腦的編碼設計論文的大牛(好像是圖靈還是什麼的),當然有更深的考慮。但從序性和數系聯絡的角度,補碼的發明是相當合理的。而這種合理性,我個人認為,正是其優點。
從機器實現的角度,並不算複雜,但相對反碼的機器實現,還是多了+1的進位延時。------------------------------------
任何一個數都可以表示為-a=2^(n-1)-2^(n-1)-a;
這個假設a為正數,那麼-a就是負數。而根據二進位轉十進位數的方法,我們可以把a表示為:a=k0*2^0+k1*2^1+k2*2^2+……+k(n-2)*2^(n-2),第(n-1)位為符號位不計算在內。
這裡k0,k1,k2,k(n-2)是1或者0,而且這裡設a的二進位位元為n位,即其模為2^(n-1),而2^(n-1)其二項展開是:1+2^0+2^1+2^2+……+2^(n-2),而式子:-a=2^(n-1)-2^(n-1)-a中,2^(n-1)-a代入a=k0*2^0+k1*2^1+k2*2^2+……+k(n-2)*2^(n-2)和2^(n-1)=1+2^0+2^1+2^2+……+2^(n-2)兩式,2^(n-1)-a=(1-k(n-2))*2^(n-2)+(1-k(n-3))*2^(n-3)+……+(1-k2)*2^2+(1-k1)*2^1+(1-k0)*2^0+1,而這步轉化正是取反再加1的規則的代數原理所在。因為這裡k0,k1,k2,k3……不是0就是1,所以1-k0,1-k1,1-k2的運算就是二進位下的取反,而為什麼要加1,追溯起來就是2^(n-1)的二項展開式最後還有一項1的緣故。而-a=2^(n-1)-2^(n-1)-a中,還有-2^(n-1)這項未解釋,這項就是補碼裡首位的1,首位1在轉化為十進位時要乘上2^(n-1),這正是n位二進位的模。
不能貼公式,所以看起來很麻煩,如果寫成代數式子看起來是很方便的。
註:n位二進位,最高位為符號位,因此表示的數值範圍-2^(n-1) ——2^(n-1) -1,所以模為2^(n-1)。上面提到的8位二進位模為2^8是因為最高位非符號位,表示的數值範圍為0——2^8-1。
按位取反 補碼