???????在計算機中,使用二進制表達數(shù)字,例如,一個字節(jié)(8位)可表示的范圍是0到255(在不考慮符號的情況下),即00000000到11111111。
考慮到數(shù)字有正負,我們第一時間想到,空出一位來表示符號位,例如0表示正,1表示負。則理論上我們表示的范圍是-127到+127。這種表達 方式簡單明了,好理解,但是有如下幾個缺點:
- 當碰到數(shù)字0的時候,這個時候有兩種表達方式,即-0和+0,這會造成一個數(shù)字有兩個表達形式
- 當計算的時候,符號位不能參加計算,增加了計算的復雜度
- 計算的時候很據(jù)符號不同,需要轉(zhuǎn)換成加法或者減法來計算,這對電路的設計不太友好,增加了設計的復雜度
所以,引入了一個全新的表達形式,補碼
原碼
在介紹補碼之前,我們先來看看幾個相關的概念,第一個就是原碼
原碼(true form)是一種計算機中對數(shù)字的二進制定點表示方法。原碼表示法在數(shù)值前面增加了一位符號位(即最高位為符號位):正數(shù)該位為0,負數(shù)該位為1(0有兩種表示:+0和-0),其余位表示數(shù)值的大小。
以一個字節(jié)為例,例如:
- +11原碼表示為00001011
- -11原碼表示為10001011
- +0原碼表示為00000000
- -0原碼表示為10000000
原碼表示有簡單易懂的優(yōu)點,但是原碼的符號位不能直接參與運算,必須和其他位分開,這就增加了硬件的開銷和復雜性。
反碼
反碼表示法規(guī)定:正數(shù)的反碼與其原碼相同;負數(shù)的反碼是對其原碼逐位取反,但符號位除外。
上面是百度百科的定義和反碼的計算方式,我們可以以一種簡單的方式概括為:
一個數(shù)的反碼為這個數(shù)的絕對值各位取反
- +11反碼和原碼表示方式相同,為00001011
- -11原碼表示為10001011,按照定義,其反碼為保留第一位符號位,其余位數(shù)取反,即11110100,按照我們簡單的定義,即為11的原碼各位取反,即00001011各位取反,也是相同的結(jié)果
- +0反碼表示為00000000
- -0反碼表示為11111111
反碼碼是數(shù)值存儲的一種,多應用于系統(tǒng)環(huán)境設置,如linux平臺的目錄和文件的默認權限的設置umask,就是使用反碼原理。
補碼
來到這邊文章的重點了,在計算機里面,定點數(shù)既不是使用原碼表示,也不是使用反碼表示,而是使用補碼
百科解釋如下
在計算機系統(tǒng)中,數(shù)值一律用補碼來表示和存儲。原因在于,使用補碼,可以將符號位和數(shù)值域統(tǒng)一處理;同時,加法和減法也可以統(tǒng)一處理。此外,補碼與原碼相互轉(zhuǎn)換,其運算過程是相同的,不需要額外的硬件電路。
首先,我們闡述下補碼的計算方式
- 正數(shù)的補碼為其原碼
- 負數(shù)的補碼為其反碼加1
例如
- +11的補碼 = 原碼 = 00001011
- -11的補碼 = 反碼 + 1 = 11110100 + 1 = 11110101
- +0的補碼 = 原碼 = 00000000
- -0的補碼 = 反碼 + 1 = 11111111 + 1 = 00000000 (高位溢出)
補碼的特性
- 一個負整數(shù)(或原碼)與其補數(shù)(或補碼)相加,和為模。
“模”是指一個計量系統(tǒng)的計數(shù)范圍。如時鐘等。計算機也可以看成一個計量機器,它也有一個計量范圍,即都存在一個“模”。
以-11舉例
-11 原碼為 10001011
-11 補碼為 11110101
相加為10000000(高位溢出)=128,這個128即為8位定點數(shù)的模
- 對一個整數(shù)的補碼再求補碼,等于該整數(shù)自身。
這個也是補碼的優(yōu)勢之一,原碼和補碼的轉(zhuǎn)換,可以使用同一套規(guī)則,我們以一個負數(shù)為例
-11的原碼為10001011
通過補碼的規(guī)則轉(zhuǎn)為之后為11110101,此為-11的補碼
該補碼再通過相同的規(guī)則轉(zhuǎn)換為(11110101的反碼加1),10001011
- 補碼的正零與負零表示方法相同。
在原碼里面,+0和-0的表示方式不同,運算和表達的時候需要增加一些額外的邏輯,在補碼里面則沒有這個煩惱,補碼的+0和-0的表示方式均為00000000(以8位為例)
- 補碼的計算的時候,符號位可以加入運算
這也是補碼的優(yōu)勢之一,這樣可以簡化電路邏輯,我們這里面舉個簡單的例子
11+(-2)
11的補碼為00001011
-2的補碼為11111110
直接相加加過為00001001=9
總結(jié)
補碼只是一種相對合理的編碼方案。這個方案在負數(shù)的機器表示中解決了3個問題:
- 數(shù)的表示
- 數(shù)的運算
- 自身邏輯意義的完整性