我們都知道二進位制只有0和1
,比如1在8
位的二進位制數字裡的原碼是
0000 0001,而7
的原碼是
0000 0111;
-1的原碼則為
1000 0001,其中第乙個紅色數字
1,表示負號,是符號位。如果是正數則為0,
-7的原碼是
1000 0111;
那麼變成補碼的話,正數的補碼和原碼相同,負數的補碼為除了第一位符號位之外,其他位0
變1,1變0
,並且最後再加1;
如:數字原碼
補碼0000 0001
0000 0001
0000 0111
0000 0111
-11000 0001
1111 1111
-71000 0111
1111 1001
於是,正數和負數就能直接通過補碼相加來計算了。
例如1+ -1= 0000 0001+ 1111 1111=1 0000 0000=0(因為運算結果的第一位是
0,代表正數,於是正數的補碼
=原碼,即為
0)(至於第一位的
1為什麼省去,應該是因為
8位不能儲存第九位的數字)
1+ -7= 0000 0001+ 1111 1001=1111 1010(由於第一位是
1,代表是負數,那麼需要將補碼轉回原碼,即先
-1,再
1 0互變一次)
= 1000 0100= -6
至於為什麼要這麼變,還要再加1
。舉例子:
0是0000 0000
-0是1000 0000
-0的補碼是
1111 1111+1=0000 0000
-1是1000 0001
-1的補碼是
1111 1110+1=1111 1111
-2是1000 0010
-2的補碼是
1111 1101+1=1111 1110
相當於0
是128,-1
是127,-2
是126,
-1+1=128=0
-2+1=127=-1
-3+1=126=-2
原因在於8
位中的第一位是符號位,因此實際上不存在
128這麼大的數字(因為
7位儲存代表是數字最大是
63),如果是這麼大,那麼就必定代表第一位是
1,定義他是符號位後,那麼就代表有
1的就是負數變過來的補碼,轉成原碼就原樣轉回去——即
-1再互換0和
1. 之前的-1
,變成補碼再運算的話,就是2的
7次方1111 1111(在8
位的情況下)
*2=1111 1111 + 1111 1111= 1 1111 1110
,省略掉第一位
1,即為
1111 1110
,是-2
的補碼,轉為原碼即為
1000 0010
即為-2
。我之前得到的結果是
4294967294,是2
的31次方(因為
32位的第一位是符號位,表示正負)
-1(因為
0即可以理解
0,又可以理解是省略掉第一位的2的
31次方,
-1則比0小
1,則-1),又由於加了
unsigned
命令,所以你輸入
-1,系統不會認為是輸入的是
-1,而是2的
31次方
-1《——因為運算算的是補碼,所以
-1補碼後乘以
2,又因為不為負,所以不會認為需要將運算後的補碼轉為負數的原碼,而是轉為正數的原碼,即為顯示結果。
負數補碼的絕對值(稱為真值)
如 -1
的原碼是
1000 0001
,補碼是
1111 1111
,絕對值是
1 0互換,即取反,然後再加1。
為什麼負數的補碼和原碼之間的轉換,都是要除符號位之外取反之後再加1呢?
假如不加1:
-1 的原碼是 1000 0001
,取反= 1111 1110
-126的原碼是
1111 1110
,取反= 1000 0001
-127 的原碼是
1111 1111
,取反= 1000 0000
-1+ -126 =1111 1111,而
-127
的不加1
取反的補碼是
1000 0000;
假如加1:
-1 的原碼是 1000 0001
,取反= 1111 1111
-126的原碼是
1111 1110
,取反= 1000 0010
-127 的原碼是
1111 1111
,取反= 1000 0001
-1+ -126 = 1000 0001,恰好是
-127
的補碼。
我們可以看出,不加1
的時候,相加之和 是正確結果
-1,加
1之後,由於三個都加
1,等式兩邊原來的
-1 =0
變成-1+2 =0+1
,正好ok。
如此推斷,假如三個數相加,如-1 + -1 + -125
-125的原碼是
1111 1101
,取反= 1000 0011
-1+ -1 =1111 1111+1111 1111=1111 1110=-2
-2 + -125=1111 1110+ 1000 0011=1000 0001= -127
又相等,
所以,並非之前不加1
的情況下,等式兩邊並非是-1和
0,而是
-1 + -1
和 -1。
所以,應該是不加一,會讓等式一邊某個數要-1
,兩個數則
-2,加
1之後則正好相等。
原碼1111
取反的實質是 用
1000 - 0111 = 0001;
補碼1001
取反的實質是 用
1000 - 0001 = 1111;
假如原碼是4位:
原碼 + 補碼 = 2的
3次方;
原碼 + 原碼取反 = 2的3次方
-1;原碼 + 原碼取反
+1 = 2的
3次方 = 原碼 + 補碼;
原碼取反+1=補碼
補碼同理,所以無論是補碼還是原碼,二者取反加一即可互推。
至於(負數)補碼的絕對值(真值),是原碼所有位取反+1
,類同上面,負數的補碼變成原碼,和正數的原碼區別,只在於第乙個正負符號不同,所以再把第一位的1變成
0,即可。
負數轉換為補碼
有些基礎還得重新拿起來,以前剛學的時候不知道為什麼,現在才真能豁然開朗。我們已經知道計算機中,所有資料最終都是使用二進位制數表達。我們也已經學會如何將乙個10進製數如何轉換為二進位制數。不過,我們仍然沒有學習乙個負數如何用二進位制表達。比如,假設有一 int 型別的數,值為5,那麼,我們知道它在計算...
負數轉換為補碼
有些基礎還得重新拿起來,以前剛學的時候不知道為什麼,現在才真能豁然開朗。我們已經知道計算機中,所有資料最終都是使用二進位制數表達。我們也已經學會如何將乙個10進製數如何轉換為二進位制數。不過,我們仍然沒有學習乙個負數如何用二進位制表達。比如,假設有一 int 型別的數,值為5,那麼,我們知道它在計算...
快速簡單地求負數的補碼和求補碼代表的負數
快速簡單地求負數的補碼和求補碼代表的負數 特點是 快速簡單實用,不用教科書的取反加一之類的麻煩方法。1 這是我認為必要的基本知識 補碼,是整數數字資料在計算機內部的儲存格式。整數分為正數,0,和負數。1位二進位制數字可以表示2個不同的狀態,2位二進位制數字可以表示4個不同的狀態,3位二進位制數字可以...