原碼:將乙個整數,轉換成二進位制,就是其原碼。如單位元組的5的原碼為:0000 0101;-5的原碼為1000 0101。
反碼:正數的反碼就是其原碼;負數的反碼是將原碼中,除符號位以外,每一位取反。如單位元組的5的反碼為:0000 0101;-5的原碼為1111 1010。
補碼:正數的補碼就是其原碼;負數的反碼+1就是補碼。如單位元組的5的補碼為:0000 0101;-5的原碼為1111 1011。
在計算機中,正數是直接用原碼表示的,如單位元組5,在計算機中就表示為:0000 0101。負數用補碼表示,如單位元組-5,在計算機中表示為1111 1011。
這兒就有乙個問題,為什麼在計算機中,負數用補碼表示呢?為什麼不直接用原碼表示?如單位元組-5:1000 0101。
我想從軟體上考慮,原因有兩個:
1、表示範圍
拿單位元組整數來說,無符號型,其表示範圍是[0,255],總共表示了256個資料。有符號型,其表示範圍是[-128,127]。
先看無符號,0表示為0000 0000,255表示為1111 1111,剛好滿足了要求,可以表示256個資料。
再看有符號的,若是用原碼表示,0表示為0000 000。因為咱們有符號,所以應該也有個負0(雖然它還是0):1000 0000。
那我們看看這樣還能夠滿足我們的要求,表示256個資料麼?
正數,沒問題,127是0111 1111,1是0000 0001,當然其它的應該也沒有問題。
負數呢,-1是1000 0001,那麼把負號去掉,最大的數是111 1111,也就是127,所以負數中最小能表示的資料是-127。
這樣似乎不太對勁,該如何去表示-128?貌似直接用原碼無法表示,而我們卻有兩個0。
如果我們把其中的乙個0指定為-128,不行麼?這也是乙個想法,不過有兩個問題:一是它與-127的跨度過大;二是在用硬體進行運算時不方便。
所以,計算機中,負數是採用補碼表示。如單位元組-1,原碼為1000 0001,反碼為1111 1110,補碼為1111 1111,計算機中的單位元組-1就表示為1111 1111。
單位元組-127,原碼是1111 1111,反碼1000 0000,補碼是1000 0001,計算機中單位元組-127表示為1000 0001。
單位元組-128,原碼貌似表示不出來,除了符號為,最大的數只能是127了,其在計算機中的表示為1000 0000。
2、大小的習慣(個人觀點)
也可以從資料大小上來理解。還是以單位元組資料為例。有符號數中,正數的範圍是[1,127],最大的是127,不考慮符號為,其表示為111 1111;最小的是1,不考慮符號為,其表示為000 0001。
負數中,最大的是-1,我們就用111 1111表示其數值部分。後面的資料依次減1。減到000 0001的時候,我們用它標示了-127。再減去1,就變成000 0000了。還好我們有符號為,所以有兩個0。把其中帶符號的0拿過來,表示-128,剛好可以滿足表示範圍。
以上只是從軟體的角度進行了分析,當然,從硬體的角度出發,負數使用補碼表示也是有其原因的,畢竟計算機中,最終實現運算的還是硬體。主要原因有三:
1、負數的補碼,與其對應正數的補碼之間的轉換可以用同一種方法----求補運算完成,簡化硬體。
如:原碼 反碼 補碼
-127 -〉127 1000 0001 -〉 0111 1110 -〉 0111 1111
127 -〉-127 0111 1111 -〉 1000 0000 -〉 1000 0001
-128 -〉128 1000 0000 -〉 0111 1111 -〉 1000 0000
128 -〉-128 1000 0000 -〉 0111 1111 -〉 1000 0000
可以發現,負數和正數求補的方法是一樣的。
2、可以將減法變為加法,省去了減法器。
在計算機中,我們可以看到,對其求補,得到的結果是其數值對應的負數。同樣,負數也是如此。
運算中,減去乙個數,等於加上它的相反數,這個小學就學過了。既然其補碼就是其相反數,我們加上其補碼不就可以了。
如:a - 127,
也就相當於:a + (-127),
又因為負數是以補碼的形式儲存的,也就是負數的真值是補碼,既然這樣,當我們要減乙個數時,直接把其補碼拿過來,加一下,就ok了,我們也可以放心地跟減法說拜拜了!
當然這也涉及到型別轉換的問題,如單位元組128,其原碼是1000 0000,其補碼也是1000 0000。這樣我們+128,或者-128,都是拿1000 0000過來相加,這樣不混亂掉了?還好,各個程式語言的編輯器對有型別轉換相關的限制。
如:(假設常量都是單位元組)
1 + 128, 真值的運算是 0000 0001 + 1000 0000 ,如果你將結果賦值給乙個單位元組有符號正數,編輯器會提示你超出了表示範圍。因為運算的兩個資料是無符號的,其結果也是無符號的129,而有符號單位元組變數最大可以表示的是127。
1 - 128,真知的運算是 0000 0001 + 1000 0000 ,因為-128是有符號,其運算結果也是有符號,1000 0001,剛好是-127在計算機中的真值。
3、無符號及帶符號的加法運算可以用同一電路完成。
有符號和無符號的加減,其實都是把它們的真值拿過來相加。真值,也就是乙個數值在計算機中的二進位制表示。正數的真值就是其原碼,負數的真值是其補碼。所以,有符號和無符號由編譯器控制,計算機要做的補過是把兩個真值拿過來相加。
這裡是我的理解:
這裡 數字表示方法為:
1byte=8位 比如數字:2 表示為2進製為 00000010
8位中左邊開始第一位表示符號位 0 表示正數 1表示負數
1byte中最大的正數就是 01111111=2的6次方+2的5次方 一直到 2的0次方 =64+32+16+8+4+2+1=127
00000000 左邊第一位0開始所以表示 +0
那麼 10000000 左邊第一位是1 但是也是代表0 是-0
+0和-0 所表示的意義 完全是一樣的
怎麼樣不浪費這個 -0的位置了 -0的2進製值就是10000000
這裡將補碼引入 就可以將這個值用起來
補碼的表示法為 原碼的
絕對值->反碼+1
所有負數都是使用補碼進行表示的
比如 -2 的就 -2的絕對值 也就是2 的原碼00000010 去除左邊第一位的符號位取反 就是1111101 在加入1 結果為 1111110 在符號位上加入1
就是 11111110
看下面的列表 可以知道 僅剩乙個10000000 就用來表示 -128了
這裡在看-127 絕對值127的原碼為:01111111 1111111->0000000->0000001->10000001
-126 絕對值
126的原碼為:01111110
1111110->0000001->0000010->10000010
-125
絕對值125的原碼為:
01111101
1111101->0000010->0000011->10000011
..........
-1 絕對值
1的原碼為 00000001
0000001
->1111110->1111111->11111111
-1的後7位 也就是 127的後7位
-2的後7位 也就是 126的後7位 只是符號位不一樣
這裡方便記憶理解為為 127>126 所以127的後七位大於126的後七位
所以 -1的後七位也大於 -2的後七位
正數的補碼就是其本身
原碼 反碼 補碼,計算機中負數的表示
原碼 將乙個整數,轉換成二進位制,就是其原碼。如單位元組的5的原碼為 0000 0101 5的原碼為1000 0101。反碼 正數的反碼就是其原碼 負數的反碼是將原碼中,除符號位以外,每一位取反。如單位元組的5的反碼為 0000 0101 5的反碼為1111 1010。補碼 正數的補碼就是其原碼 負...
原碼 反碼 補碼,計算機中負數的表示
原碼 將乙個整數,轉換成二進位制,就是其原碼。如單位元組的5的原碼為 0000 0101 5的原碼為1000 0101。反碼 正數的反碼就是其原碼 負數的反碼是將原碼中,除符號位以外,每一位取反 如單位元組的5的反碼為 0000 0101 5的反碼為1111 1010。補碼 正數的補碼就是其原碼 負...
原碼 補碼 反碼及計算機中負數的表示
第一位為符號位,後面的為數字的二進位制表示。eg 127 和 127 的 8位原碼為 0111 1111,1111 1111 正數的反碼為其原碼 負數的反碼,符號位不変,後面的取反。eg 1的8位原碼和反碼為 00000001 原 00000001 反 1的8位反碼為 10000001 原 1111...