原碼反碼補碼詳解
原碼:
原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其余位表示值. 比如如果是8位二進制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
第一位是符號位. 因為第一位是符號位, 所以8位二進制數的取值範圍就是:
[1111 1111 , 0111 1111],即:
[-127 , 127]
例如5和-5的原碼:
00000000 00000000 00000000 00000101 //為5
10000000 00000000 00000000 00000101 //為-5
計算機中並沒有減運算,減運算實際是加一個負數的運算,這也就是為什麽正數之間的加運算會比減運算快的原因,減運算需要做更多的處理來讓計算機解讀成能理解的加運算,例如5-5計算機要處理成5+(-5),原碼在高位用0和1解決了區分正負的問題,但是又引來的新的問題,因為我們都知道5+(-5)是等於0的,但是我們來看看原碼之間的運算結果:
00000000 00000000 00000000 00000101+10000000 00000000 00000000 00000101
=10000000 00000000 00000000 00001010
10000000 00000000 00000000 00001010的原碼並不是我們期待的0,而是-10,5+(-5)=-10這肯定不是我們要的結果,不僅如此原碼正數高位為0,所有負數高位為1,這個時候會出現兩個0的情況,一個為正0,一個為負0,這顯然不太合理,0是沒有正負的,為了解決第一個問題後來又引入了一個新的概念,那就是反碼。
反碼:
反碼的表示方法是:正數的反碼是其本身;負數的反碼是在其原碼的基礎上, 符號位不變,其余各個位取反。
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
可見如果一個反碼表示的是負數, 人腦無法直觀的看出來它的數值. 通常要將其轉換成原碼再計算。
一個正數和自身對應的負數的反碼互為補數,因此減去該正數和加上該正數對應的負數的反碼結果是一樣的。
例如5和-5
00000000 00000000 00000000 00000101 //正數5和上面原碼及普通二進制一樣的表示
11111111 11111111 11111111 11111010 //-5的反碼是5的二進制(或者說原碼、反碼都可以,因為都一樣)0和1的反轉
00000000 00000000 00000000 00000101+11111111 11111111 11111111 11111010
=11111111 11111111 11111111 11111111
這裏的11111111 11111111 11111111 11111111是00000000 00000000 00000000 00000000的反碼,所以是-0,這樣反碼的出現就解決了正負數字的運算問題,但是還存在一個問題,就是上面的0是兩個,一個為正0,全為0,一個為負0,全為1。為了解決這個問題,又引入了補碼的概念。
補碼:
補碼的表示方法是:正數的補碼就是其本身;負數的補碼是在其原碼的基礎上, 符號位不變, 其余各位取反, 最後+1. (即在反碼的基礎上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]補
[-1] = [10000001]原 = [11111110]反 = [11111111]補
對於負數, 補碼表示方式也是人腦無法直觀看出其數值的. 通常也需要轉換成原碼在計算其數值.
5的反碼:00000000 00000000 00000000 00000101
5的補碼:00000000 00000000 00000000 00000101
-5的反碼:11111111 11111111 11111111 11111010
-5的補碼:11111111 11111111 11111111 11111011 //就是在-5的反碼基礎上+1
00000000 00000000 00000000 00000101+11111111 11111111 11111111 11111011
=00000000 00000000 00000000 00000000 //5的補碼+(-5的補碼)=0且0沒有正負號
總結:二進制不能表示負數,而原碼雖然能表示負數,但無法進行正負數運算及兩個0的問題,反碼解決正負數運算的問題然後還保留著兩個0的問題,只有補碼完美解決了正負數運算問題同時還解決了兩個不同符號的0的問題
原碼反碼補碼詳解