什么是补码,怎么求补码
文章目錄
- 1 前言
- 2 為什么要有補碼?
- 3 什么是補碼?
- 4 什么才是正真的補碼?
1 前言
我的上一篇文章談論到在匯編語言中
為什么 SHL 和 SAL 相同,而 SHR 和 SAR 不同
由此產生的疑惑更多了
到底什么是符號位? 進而補碼又是什么?
2 為什么要有補碼?
理由很簡單,計算機內部只有加法器,并沒有減法器
所以在計算機中,在我們人類眼中很簡單的算術運算 2 - 3 = -1
計算機是無法完成的,那么依照計算機只能做加法,很顯然的想到了 2 + (-3) = -1
因此數在計算機中必然要有特定的表示,那么補碼就誕生了。
3 什么是補碼?
無符號(unsigned)的一個字節的數表示如下:
0000 0000 = 0 0000 0001 = 1 0000 0010 = 2 ... 1111 1111 = 255有符號數(signed)的一個字節的數表示如下:
0000 0000 = 0 0000 0001 = 1 0000 0010 = 2 ... 1000 0000 = 0 1000 0001 = -1 ... 1111 1111 = -127問題出現了,0000 0000 和 1000 0000 都代表著數字 000
不僅如此,且計算兩個數相加會非常復雜,比如:
0000 0010 + 1000 1100 ---------------???? ????這必然給計算機運算器帶來麻煩
于是約定,將1000 0000 設置為 -128,了解更多 點這里
因此范圍被定義為: ?128-128?128 ≤\leq≤ X ≤\leq≤ +127+127+127
雖然兩個 0 的表示問題解決了,但是計算問題依舊相當復雜,于是就引進了補碼
幾乎所有的教材都這樣寫到:
正數的補碼就是原碼
負數的補碼是符號位不變(1),其余位取反,然后加一
并且給出以下定義:
一個有符號數的最高位為符號位
0 代表這個數為正數
1 代表這個數為負數
依照這種定義,我們簡單的來進行幾個運算:
【例1】用補碼計算 45 + 24。
正常答案69也是輕而易舉的求出來了
【例2】用補碼計算45 - 38。
0010 1101 + 1101 1010 ----------------- (1) 0000 0111計算這一題的時候就有些猶豫了,因為進位已經到了符號位
那么我的符號位到底參與運算嗎?
常理來說,符號位顧名思義,代表著數的正負,怎么可以參與運算呢?
事實卻恰恰相反,符號位參與運算的結果才是正確的,如上例所示。
4 什么才是正真的補碼?
上述的例子說明了一個非常矛盾的事情
把一個數的最高位定義為了符號位,計算中符號位卻能參與運算
想必這也是很多人蒙在鼓里的地方了
補碼的定義(以888位字長數為例):
| XXX | 000 ≤\leq≤ XXX ≤\leq≤ +127+127+127 |
| 282^828-XXX | ?128-128?128 ≤\leq≤ XXX <0<0<0 |
也就是說,正數的補碼就是原碼
而反碼的補碼等于位數 282^828 減去 XXX 的絕對值 ∣X∣|X|∣X∣,例如 ?38-38?38 的補碼:
所以 ?38-38?38 的補碼為1101 1010
在這種定義下,沒有反碼的概念,也沒有符號位的概念
參考:
[1] Signed Int: Bias/Excess Notation
總結
以上是生活随笔為你收集整理的什么是补码,怎么求补码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java中对象的储存区
- 下一篇: C语言-动态创建二维数组