標籤:簡單 article 說明 映射 str tail https 注意 換算
目錄
- 介紹
- 原碼
- 反碼
- 補碼
- 為什麼八位位元表示範圍為-128~+127?
介紹
電腦中的符號數有三種表示方法,即原碼、反碼和補碼。三種表示方法均有符號位和數值位兩部分,符號位都是用0表示“正”,用1表示“負”,而數值位,三種表示方法各不相同。
原碼
原碼(true form)是一種電腦中對數位二進位定點表示方法。原碼錶示法在數值前面增加了一位符號位(即最高位為符號位):正數該位為0,負數該位為1(0有兩種表示:+0和-0),其餘位表示數值的大小。
優點:
簡單直觀;例如,我們用8位二進位表示一個數,+11的原碼為00001011,-11的原碼就是10001011
缺點:
原碼不能直接參加運算,可能會出錯。例如數學上,1+(-1) = 0,而在二進位中00000001+10000001=10000010,換算成十進位為-2。顯然出錯了。
反碼
反碼錶示法規定:正數的反碼與其原碼相同;負數的反碼是對其原碼逐位取反,但符號位除外。
補碼
補碼錶示法規定:正數的補碼與其原碼相同;負數的補碼是在其反碼的末位加1。
在電腦系統中,數值一律用補碼來表示和儲存。原因在於,使用補碼,可以將符號位和數範圍統一處理;同時,加法和減法也可以統一處理。此外,補碼與原碼相互轉換,其運算過程是相同的,不需要額外的硬體電路。
為什麼八位位元表示範圍為-128~+127?
首先八位位元0000 0000 ~1111 1111,一共可以表示28=256位元,如果表示不帶正負號的整數可以表示0~255。計算方法就是二進位與十進位之間的轉換。
如果想要表示有符號整數,就要將最前面一個二進位位作為符號位,即0代表正數,1代表負數,後面7位為數範圍,這就是原碼定義。這樣在現實生活中完全沒有問題,但在電腦中就出現了問題。
數的表示
在原碼中,0的表示有兩種(+0)0000 0000、(-0)1000 0000,這樣就產生了編碼映射的不唯一性,在電腦上就要區分辨別。然而+0、-0卻沒有什麼現實意義。
數的運算
為瞭解決上述數的表示問題,我們可以強制把轉換後的10000000強制認定為-128。但這又出現了一個新的問題就是數的運算。數學上,1+(-1)=0,而在二進位中00000001+10000001=10000010,換算成十進位為-2。顯然出錯了。所以原碼的符號位不能直接參与運算,必須和其他位分開,這就增加了硬體的開銷和複雜性。
這個時候就要引入補碼,補碼錶示法規定:正數的補碼與其原碼相同;負數的補碼是在其反碼的末位加1。反碼定義為:正數的反碼與其原碼相同;負數的反碼是對其原碼逐位取反,但符號位除外。
問題1:為什麼要引入補碼呢?
先解決第一個問題,引入補碼是為瞭解決電腦中數的表示和數的運算問題,使用補碼,可以將符號位和數範圍統一處理,即引用了模運算在數理上對符號位的自動處理,利用模的自動丟棄實現了符號位的自然處理,僅僅通過編碼的改變就可以在不更改機器物理架構的基礎上完成的預期的要求。
問題2:負數補碼定義為什麼是相對應的正數原碼取反加一?
要解決第二個問題同時理解補碼,首先要理解“模”。
模的概念可以協助理解補數和補碼。
“模”是指一個計量系統的計數範圍。如時鐘等。電腦也可以看成一個計量機器,它也有一個計量範圍,即都存在一個“模”。例如:
時鐘的計量範圍是0~11,模=12。表示n位的電腦計量範圍是0~2(n)-1, 模=2(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位二進位系統的模為29。在這樣的系統中減法問題也可以化成加法問題,只需把減數用相應的補數表示就可以了。把補數用到電腦對數的處理上,就是補碼。
接下來就是取反加一的來源:
例如-8,可以看做0-8,即0000 0000 - 0000 1000,小減大,向高位借一,即1 0000 0000 - 0000 1000 = 1111 1000,這個可以看做用模數來減去該數,會得到該數的補數。同時上式也可以看做 (1111 1111 - 0000 1000)+1,即0000 1000 取反加1。
負數補碼定義是相對應的正數原碼取反加一,這個同負數的反碼末尾加一是同樣的效果。注意看反碼的定義。取反加一是逐位取反,包括符號位。
對一個正數的原碼取反加一,得到這個正數對應負數的補碼。例如~6=-7,而且加一之後會多出一個八進位補碼1000 0000,而這個補碼就對應著原碼1000 0000,數字位同時當做符號位即-128。
根據以上內容我們就可以來解釋八位位元的表示範圍
八位二進位正數的補碼範圍是0000 0000 ~ 0111 1111 即0 ~ 127,負數的補碼範圍是正數的原碼0000 0000 ~ 0111 1111 取反加一(也可以理解為負數1000 0000 ~ 1111 1111化為反碼末尾再加一)。
所以得到 1 0000 0000 ~ 1000 0001,1000 0001作為補碼,其原碼是1111 1111(-127),依次往前推,可得到-1的補碼為1111 1111,那麼補碼0000 0000的原碼是1000 0000符號位同時也可以看做數字位即表示-128,這也解釋了為什麼127(0111 1111)+1(0000 0001)=-128(1000 0000)。
總結: 在電腦中資料用補碼錶示,利用補碼統一了符號位與數值位的運算,同時解決了+0、-0問題,將空出來的二進位原碼1000 0000表示為-128,這也符合自身邏輯意義的完整性。因此八位位元表示範圍為-128~+127。在電腦運算的時候,都是以補碼的方式來運算的。
電腦內部運算的實質是進行補碼運算,接下來舉例說明
假如 A = 60, B = 13
A+BA的原碼為: 0011 1100 A的反碼為: 0011 1100A的補碼為: 0011 1100B的原碼為: 0000 1101 B的反碼為: 0000 1101B的補碼為: 0000 1101A + B 0011 1100 0000 1101-------------- 0100 1001 0100 1001轉換為10進位整數就是73 A-B = A + (-B)A的原碼為: 0011 1100 A的反碼為: 0011 1100A的補碼為: 0011 1100-B的原碼為: 1000 1101 -B的反碼為: 1111 0010-B的補碼為: 1111 0011A - B = 0011 1100 1111 0011-------------- 0010 11110010 1111轉換為10進位整數就是47需要注意的是如果得到的結果是正數,則補碼就是原碼,但是如果得到的結果是負數,則需要將補碼-1取反變成原碼後再轉換成整數B - A -A的原碼為: 1011 1100-A的反碼為: 1100 0011-A的補碼為: 1100 0100B的原碼為: 0000 1101 B的反碼為: 0000 1101B的補碼為: 0000 1101B - A = 1100 0100 0000 1101-------------- 1101 0001根據補碼符號位可以看出結果為負數,所以需要先-1轉換為反碼1101 0000,然後符號位不變,取反為原碼為1010 1111即為-47
參考:
為什麼八位位元表示範圍為-128~+127?
原碼、反碼、補碼