在電腦中,定點數有三種表示方法原碼,反碼和補碼
原碼:
任何一個正數都可以轉換成0和1的形式,然後以二進位的形式存放在電腦裡面,一個佔8個位元組的儲存單元,可以存入的無符號的整數的範圍是0到255,總共256個數。
負數在電腦中的存放方法與正數一樣,只不過加了一個符號位。例如一個佔8個位元組的儲存單元,它能存放的有符號的整數範圍是-127到正127,共255個數。它把第一位留出來,用作符號位。如果第一位是0,那麼代表是正數。是1則代表是負數。
例如中,10001001 代表的是-9,第一個1(標記為紅色的),是符號位,代表這個數是負數。
例如: 10001000 代表-8
00001000 代表+8
反碼:
正數的反碼是它本身。負數的反碼,是它的絕對值的原碼取反,取反。也就是1變成0,0變成1.
例如:-8的反碼是 11110111
具體求解過程,-8的絕對值是+8,+8的原碼是 00001000,直接按位取反,就變成了11110111
在網上,別人講到這個地方的時候,總說取反的時候要把符號位帶上,有時說得不清楚,讓人混淆。其實帶符號位取反可以,也可以不帶符號位取反,取反後再加上符號位。例如上面的,是帶符號位取反的。下面我們不帶符號位取反(不帶符號位取反,也就是不管符號位,把符號位放在一邊)。
不帶符號位取反的話,那麼我們只看後面的7位。-8的原碼為10001000,我們只看後面的7位,那就是0001000,我們把這7位取反得到1110111.因為我們要求-8的反碼,那麼在需要在上面求出的反碼的基礎上,加上符號位1了,最後結果還是11110111.與上面的結果是一樣的。
補碼:
正數的補碼是它本身,負數的補碼是它的反碼加1,例如-8的補碼是11111000.
例子來自百度百科,我自己重新演算了一遍。
(1) 已知原碼,求補碼。
例:已知某數X的原碼為10110100B,試求X的補碼和反碼。
反碼:絕對值原碼,按位取反,得11001011
補碼:反碼+1,得11001100
(2) 已知補碼,求原碼。
分析:按照求負數補碼的逆過程,數值部分應是最低位減1,然後取反。但是對位元來說,先減1後取反和先取反後加1得到的結果是一樣的,故仍可採用取反加1 有方法。
例:已知某數X的補碼11101110B,試求其原碼。
有兩種方法:
一是先減1,再取反。
補碼減1得 11101101 ,取反得 10010010
補碼取反 10010001 ,加1得 10010010
為什麼需要反碼及補碼:
其實用原碼,就可以表示所有數,那麼為什麼還要反碼以及補碼呢?之所以有反碼,是在硬體中實現減法不太方便,所以需要把減法轉換成加法來實現,比如1-1就相當於1+(-1),比如1+(-1)本身等於0,如果按照原碼來計算 那就是00000001+10000001最後的結果就是10000010,也就是-2了,如果負數是用反碼錶示的,那麼就成了00000001(正1的原碼,也是1的反碼)+11111110=11111111,也就是(-0)了,但是因為電腦裡面不存在正0以及負0之說,所以最後又提出了補碼的概念,補碼就是在反碼的基礎上加1,加了補碼後,就成了00000001(正1的原碼,也是1的補碼)+11111111=100000000,最前面的一個1超出了範圍,會被拋棄,最後結果就是0了。
原碼,反碼,補碼的表示範圍:
原碼的表示範圍 -128到127(10000000本身代表-0,但電腦中0沒有正負之分,所以就代表-128,可以通過sbyte的MinValue屬性得知)
反碼的表示範圍 -127到127
補碼的表示範圍 -128到127(10000000到11111111分別代表-128到-1)
0的原碼,反碼,補碼:
0的原碼 00000000 和10000000
0的反碼 00000000和 11111111
0的補碼 00000000
關於溢出:
兩個正數相加,或者兩個負數相加,它們的值有可能超過了8個位元組能表示的範圍,這個時候最高位就會溢出。
127+127=01111111+01111111=11111110=--126 兩個正數相加不可能是負數
(次高位有進位,但是符號位卻沒有進位,這時候產生溢出)
-127+(-127)=10000001+10000001=1 00000010 兩個負數相加不可能是正數
(次高位沒有進位,但是符號位卻有進位,符號位的進位被丟棄)