原碼、反碼、補碼、「溫故而知新」
以前好像數位電路裡當基礎知識學過,一直到後來學微控制器都用到,現在在自學dsp的過程中,又遇到這個最基礎的問題。一扯到2進製我就發暈,總是覺得不那麼習慣。現在作了個總結,希望以後再不會在這個問題上感到困惑。
1綜述:
數在計算機中是以二進位制形式表示的。有兩種辦法表示實數:
一種是定點,就是小數點位置是固定的。一般都預設小數點在最後一位數的右方,表示整數。
一種是浮點,就是小數點位置不固定。浮點數採用底數+尾數的格式,其實就是所說的科學記數法。小數點在底數的最左面,尾數表示實際應將小數點向左(尾數為+)或向右(-)移動的位數。
數又分為有符號數和無符號數。
原碼、反碼、補碼都是有符號定點數的表示方法。
有符號數的最高位為符號位,0是正,1是負。
2 原碼、反碼、補碼
原碼就是這個數本身的二進位制形式。如:00000001 就是+1 10000001 就是-1。
反碼表示法規定:正數的反碼與其原碼相同;負數的反碼是對其原碼逐位取反,但符號位除外。
補碼表示法規定:正數的補碼與其原碼相同;負數的補碼是在其反碼的末位加1。
例子:+1011
原碼:01011
反碼:01011 //正數時,反碼=原碼
補碼:01011 //正數時,補碼=原碼
-1011
原碼:11011
反碼:10100 //負數時,反碼為原碼取反
補碼:10101 //負數時,補碼為原碼取反+1
+0.1101
原碼:0.1101
反碼:0.1101 //正數時,反碼=原碼
補碼:0.1101 //正數時,補碼=原碼
-0.1101
原碼:1.1101
反碼:1.0010 //負數時,反碼為原碼取反
補碼:1.0011 //負數時,補碼為原碼取反+1
3關於0的問題:
數0的原碼有兩種形式: [+0]原=00000000b [-0]原=10000000b
數0的反碼有兩種形式: [+0]反=00000000b [-0]反=11111111b
數0的補碼是唯一的 : [+0]補=[-0]補=00000000b
假設機器能處理的位數為8.即字長為1byte,
原碼和反碼能表示數值的範圍為:
(-127~-0 +0~127)共256個,其中都有兩個0
在補碼中用(-128)代替了(-0),所以補碼的表示範圍為:
(-128~0~127)共256個,負數128個,0和正數128個。
注:其中(-128)沒有相對應的原碼和反碼, (-128) = (10000000)
圖中可以直觀的看出補碼的規律
4下面是原碼、反碼進行運算時遇到的問題(0的問題):
有了數值的表示方法就可以對數進行算術運算.但是很快就發現用帶符號位的原碼進行乘除運算時結果正確,而在加減運算的時候就出現了問題,
如下: 假設字長為8bits
( 1 ) 10- ( 1 )10 = ( 1 )10 + ( -1 )10 = ( 0 )10
(00000001)原 + (10000001)原 = (10000010)原 = ( -2 ) 顯然不正確.
因為在兩個整數的加法運算中是沒有問題的,於是就發現問題出現在帶符號位的負數身上,對除符號位外的其餘各位逐位取反就產生了反碼.反
碼的取值空間和原碼相同且一一對應. 下面是反碼的減法運算:
( 1 )10 - ( 1 ) 10= ( 1 ) 10+ ( -1 ) 10= ( 0 )10
(00000001) 反+ (11111110)反 = (11111111)反 = ( -0 ) 有問題.
( 1 )10 - ( 2)10 = ( 1 )10 + ( -2 )10 = ( -1 )10
(00000001) 反+ (11111101)反 = (11111110)反 = ( -1 ) 正確
這個問題出現在(+0)和(-0)上,在人們的計算概念中零是沒有正負之分的。所以有兩個表示的0不適合計算機的運算。
在補碼中用(-128)代替了(-0),統一正0和負0
補碼的加減運算如下:
( 1 ) 10- ( 1 ) 10= ( 1 )10 + ( -1 )10 = ( 0 )10
(00000001)補 + (11111111)補 = (00000000)補 = ( 0 ) 正確
( 1 ) 10- ( 2) 10= ( 1 )10 + ( -2 )10 = ( -1 )10
(00000001) 補+ (11111110) 補= (11111111)補 = ( -1 ) 正確
5補碼記數法中的運算規則
補碼中符號位要與有效值部分一起進行運算。
兩個用補碼表示的數相加時,如果最高位(符號位)有進製,則進製被捨棄。
例如:加0111和1011結果是0010(0111+1011=10010,捨去最左邊的1,結果為0010,長度保持4位)
採用2的補碼記數法的機器需要知道的只是如何去加和求反就夠了。
[x+y]補= [x]補+ [y]補
[x-y]補= [x]補+ [-y]補
若已知[y]補,求[-y]補的方法是:將[y]補的各位(包括符號位)逐位取反再在最低位加1即可。例如:[y]補= 101101 [-y]補= 010011
例如,減法問題7-5與加法問題7+(-5)是相同的。
因此,如果機器被請求從7(儲存為0111)中減5(儲存為0101),它首先將5改變為-5(表示為1011),
然後執行0111+1011的加法過程取得0010,它表示2。
7補碼與原碼的相互轉換過程是相同的。
已知乙個數的補碼,求原碼的方法是:
(1)如果補碼的符號位為「0」,表示是乙個正數,所以補碼就是該數的原碼。
(2)如果補碼的符號位為「1」,表示是乙個負數,求原碼的操作是:符號位為1,其餘各位取反,然後再末位加1。
例如,已知乙個補碼為11111001,則原碼是10000111(-7):因為符號位為「1」,表示是乙個負數,所以該位不變,仍為「1」;其餘7位
1111001取反後為0000110;再加1,所以是10000111。
所以,求補碼的運算可以使原碼和補碼互相轉換。乙個原碼的補碼的補碼還是他本身。
8總結所以補碼的意義就在於:
(1)補碼統一正0和負0
(2)補碼中符號位要與有效值部分一起進行運算。
(3)使減法運算轉換為加法運算。 [a-b]補=[a]補+[-b]補
附錄:補碼的身世——「模」的概念:
「模」是指乙個計量系統的計數範圍。如時鐘等。計算機也可以看成乙個計量機器,它也有乙個計量範圍,即都存在乙個「模」。例如:
時鐘的計量範圍是0~11,模=12。
表示n位的計算機計量範圍是0~2(n)-1,模=2(n)。【注:n表示指數】
「模」實質上是計量器產生「溢位」的量,它的值在計量器上表示不出來,計量器上只能表示出模的餘數。任何有模的計量器,均可化減法為
加法運算。
例如: 假設當前時針指向10點,而準確時間是6點,調整時間可有以下兩種撥法:
一種是倒撥4小時,即:10-4=6
另一種是順撥8小時:10+8=12+6=6
在以12模的系統中,加8和減4效果是一樣的,因此凡是減4運算,都可以用加8來代替。
對「模」而言,8和4互為補數。實際上以12模的系統中,11和1,10和2,9和3,7和5,6和6都有這個特性。共同的特點是兩者相加等於模。
對於計算機,其概念和方法完全一樣。n位計算機,設n=8, 所能表示的最大數是11111111,若再加1稱為100000000(9位),但因只有8位,
最高位1自然丟失。又回了00000000,所以8位二進位制系統的模為2(8)。 在這樣的系統中減法問題也可以化成加法問題,只需把減數用相應的
補數表示就可以了。
把補數用到計算機對數的處理上,就是補碼。
溫故而知新
學習講究的是溫故而知新.1,計畫。做任何事情前都要有計畫,因為機會,總是給有準備的人準備的。做個計畫,每天學習多長時間,每天戶外運動多長時間,聽英語多長時間等等!2,知新。提前預習新的課程,只有這樣,才能知道課堂上講的 是重點,是你沒聽懂的知識,才可以游刃有餘的去回答老師的問題。3,鞏固。無 理,課...
初中生演講稿 溫故而知新
四 端正態度,提公升高度 考試在即,有序複習,總會有個別自動放棄的同學。給自己貼上 學不會 的標籤,覺得複習改變不了什麼。但是我想告訴你,不是你學不會,是你沒有端正學習態度,從現在開始,請用積極的態度對待每一堂課,每乙份作業,每一次測驗,不要對自己說 學不會 請記住,只要努力就一定會有新的發現 新的...
關於學習的勵志名言學而時習之溫故而知新
關於學習的勵志名言 學而時習之,溫故而知新 古今中外有學問的人,有成就的人,總是十分注意積累的。知識就是機積累起來的,經驗也是積累起來的。我們對什麼事情都不應該像過眼雲煙。不要企圖活在別人的激勵中,自勵才是最有效的激勵方式。沒有人能真正改變你,只有你自己才能改變自己。2 苦難是一筆財富,它會錘煉人的...