下面舉例說明求負數的補碼的補碼 -1的補碼是0xFFFF. 它是這樣求的: -1的原碼: 1000 0000 0000 0001 , 數值位按位求反: 0xFFFE==1111 1111 1111 1110, 末位加1: 0xFFFF==1111 1111 1111 1111 現在還按這個補碼的求法, 作用在0xFFFF上, 0xFFFF : 1111 1111 1111 1111 數值位按位求反: 1000 0000 0000 0000 末位加1: 1000 0000 0000 0001, 這樣又得到了-1。 就像求負數的絕對值,彼此導來導去都可以。 ************************************************** *************************
************************************************** ************************* 補碼的計算和引進補碼的原因: 數值有正負之分,計算機就用壹個數的最高位存放符號(0為正,1為負). 這就是機器數的原碼了.假設機器能處理的位數為8.即字長為1byte, 原碼能表示數值的範圍為(-127~-0 +0~127)***256個. 有了數值的表示方法就可以對數進行算術運算. 但是很快就發現用帶符號位的原碼進行乘除運算時結果正確, 而在加減運算的時候就出現了問題,如下: 假設字長為8bits (1)10 - (1)10= (1)10+ (-1)10 = (1)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)上,在人們的計算概念中零是沒有正負之分的. 於是就引入了補碼概念. 負數的補碼就是對反碼加壹,而正數不變,正數的原碼反碼補碼是壹樣的. 在補碼中用(-128)代替了(-0),所以補碼的表示範圍為:(-128~0~127)***256個.已知某數的補碼, 先求某數的反碼,然後在對反碼+1,就得到某數的原碼.比如: 已知某個數的補碼是:10100110 先對10100110求反,得:11011001 再對11011001加1,得: 11011010 那麽這個數為-86 原碼表示的範圍為:-(2^(n-1)-1)~+(2^(n-1)-1), 反碼表示的範圍為與原碼壹樣. 補碼表示的範圍為:-2^(n-1)~+(2^(n-1)-1), 其中n為機器字長。 註意: 0的補碼是唯壹的,為0000,0000 [+0]補=[-0]補=0000,0000 -0的反碼為1111,1111 8bit表示數值時(-128)沒有相對應的原碼和反碼, (-128) = (10000000)
/*由此可見:負數的最大值沒有補碼和原碼,只有壹個二進制表示,該二進制表示與真實值之間沒有數學聯系,所以知道壹個數的補碼,利用取反加1的方法求其原碼是有限制性的,比如8bit表示數時,(-128)就無法用這種方法來求其原碼,因為在補碼系統中(-128)的替代了(-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 ) 正確 所以補碼的設計目的是: ⑴使符號位能與有效值部分壹起參加運算,從而簡化計算機的運算規則. ⑵使減法運算轉換為加法運算,進壹步簡化計算機中運算器的線路設計 所有這些轉換都是在計算機的最底層進行的,而在我們使用的匯編、C等其他高級語言中使用的都是原碼。 看了上面這些大家應該對原碼、反碼、補碼的知識印象更深了吧!! ************************************************** ************************
************************************************** ************************ 下面介紹2的補碼記數法 圖1顯示了兩個完整的2的補碼系統:壹個是基於長度為3的位模式, 另壹個是基於長度為4的位模式。 這種系統的構造方法是:從相應長度的0的串(例子中用3位和4位)開始, 用二進制記數的方式壹直記數到位模式是由壹個0後面跟隨盡可達到的數目1組成(列中是011和0111)為止。 這些位模式表示值0,1,3,…。表示負數的位模式是通過從相應長度的1的串開始,然後用二進制倒記數的方式記數, 壹直到位模式是由壹個1和隨後盡可能達到的數目0所組成為止。 這些位模式表示值-1,-2,-3,…。 如果這種倒記數的方法使用時太困難,也可以從表最底部的位模式開始, 向上記數。即從由壹個1和隨後盡可能達到的個數0組成的位模式開始壹直到全 由1組成的位模式為止。