上來先敲黑板,說重點(重要的事情說三遍):
- 計算機中以補碼進行存儲計算
- 計算機中以補碼進行存儲計算
- 計算機中以補碼進行存儲計算
所以,一切的運算都要先得到數據的補碼,不要上來就拿原碼在那幹,得到的結果會漫天飛舞,正負數一起算會算到你懷疑人生。。可以嘗試將十進制數字的二進制打印出來看看,正數還算正常,負數的那玩意是什麼鬼(e.g.
-3=11111111111111111111111111111101
)。。
正數
正數的原碼、反碼和補碼都一樣(不要問我爲什麼,就是這麼規定的。。我也很無奈啊。。)
負數
負數的反碼是符號位不變,其餘爲取反。負數的補碼是其反碼加一。
負數的計算方式,注意這裏是算負數即計算(~X + 1
),以計算8
的負數爲例:
8
的二進制表示爲1000
,由於是正數,手動在前面補零,變爲:01000
- 由於正數的補碼爲本身,所以其補碼爲:
01000
- 取反運算:
01000
按位取反,得到10111
,那麼10111
是哪個幸運兒的補碼呢?- 由於正數的補碼最高位肯定是
0
,而此時的10111
最高位爲1
,那麼它鐵定是一個負數的補碼- 負數的補碼計算方式是:原碼->除最高位外按位取反得反碼->反碼加一
- 反之,求原碼的方式就變爲:補碼減一->除最高位外按位取反
10111
,減一得到10110
,除最高位按位取反:11001
,即-9
- 結果就出來了:
-9 + 1 = -8
,即-X = ~X + 1
補充
還有需要說明的一點,以正數
6
爲例,它的二進制是0110
,加上一位符號位,標記爲00110
(標記一位和補全爲8
位似乎都一樣,我習慣多加一位,好理解),由於正數的反碼和補碼都與原碼相同,所以6的反碼和補碼都是00110
。但是~6
的結果是-7
。這裏需要注意,反碼 與 取反 並不是一回事。另外取反和負數也不是一回事。
注意邏輯思維:對於正數
A
求(~A
)的過程是:A
轉二進制,求到A
的補碼,按位取反,假定得到的結果是X
,那麼X
是要求的結果B
的補碼,接下來就要想辦法求B
。即公式:A補反 = B補
附錄
~9的計算步驟:
轉二進制:0 1001
計算補碼:0 1001
按位取反:1 0110
_____
轉爲原碼:
按位取反:1 1001
末位加一:1 1010
符號位爲1是負數,即-10
--snip--
~-9的計算步驟:
轉二進制:1 1001
計算補碼:1 0111
按位取反:0 1000
_____
轉爲原碼:
正數的補碼和原碼相同,仍爲:0 1000,即8