爲什麼要用?
計算機內部採用二進制表示數值。如十進制數10用二進制數表示爲1010。設計算機字長爲8,即1Byte。最高位表示符號,0爲正,1爲負
來看看用原碼錶示的數在進行加減乘除運算是會有什麼問題:
- 十進制:1-1=1+(-1)=0
- 原碼:(0000 0001)-(0000 0001)=(0000 0001)+(-0000 0001)=(0000 0001)原+(1000 0001)原=(1000 0010)原=-2,顯然不正確
以上的運算說明了負數(也就是帶符號數字,正數沒問題)原碼運算在某些時候得不到正確結果。
再來看反碼錶示進行加減乘數運算會有什麼問題:
- 十進制:1-1=1+(-1)=0
- 反碼:(0000 0001)-(0000 0001)=(0000 0001)+(-0000 0001)=(0000 0001)反+(1111 1110)反=(1000 0000)反=-0,出現了負0.
一般不區分+0、-0,用反碼就會出現這樣的問題。
最後看看補碼運算:
- 十進制:1-1=1+(-1)=0
- 補碼:(0000 0001)-(0000 0001)=(0000 0001)+(-0000 0001)=(0000 0001)補+(1111 1111)補=(0000 0000)補=0
補碼具有自己獨特的優點,用補碼連同符號位一起運算沒有出現原碼、反碼的問題,這就是爲什麼現代計算機普遍採用補碼運算的原因。
計算方法:
由於正數加減運算不存在此問題,所以正數沒有反碼、補碼,或者說正數的原碼、反碼、補碼都一樣
原碼:負數的原碼爲1|x|
反碼:負數的反碼,符號位不變,數值取反
補碼:負數的反碼加1(會影響符號位)
範圍解疑
這裏以byte爲例來解釋一下取值的範圍。byte佔一個字節,是8位。如果是無符號類型的整數,那麼原碼最大值11111111,所以原碼範圍就是0---255(也就是0~~2^8-1),總共256個數。
對於有符號類型的byte值,那麼原碼最大值應該是01111111(第一位的1代表負數符號),最小值應該是11111111,所以原碼範圍是(-127~-0 +0~127),總共256個數。但是在有符號原碼進行加減運算時的問題(原碼運算不正確,反碼出現+0、-0),所以出現了補碼。對於十進制:127 + 1 = -128 ,補碼算法:01111111 + 00000001 = 10000000 ,這裏的10000000原碼就是-0,所以在計算機中1000000的補碼錶示的就是 -128。需要注意的是:-128是沒有原碼和反碼的,只有補碼!
總結:
1>補碼的設計目的是:
⑴ 使符號位能與有效值部分一起參加運算,從而簡化運算規則。補碼機器數中的符號位,並不是強加上去的,是數據本身的自然組成部分,可以正常地參與運算。
⑵ 使減法運算轉換爲加法運算,進一步簡化計算機中運算器的線路設計。
2>反碼是原碼與補碼轉換的一箇中間過渡,使用較少。
3>所有這些轉換都是在計算機的最底層進行的,而在我們使用的彙編、c等其他高級語言中使用的都是原碼。