前言 ´・ᴗ・`
- 二進制數有常見的三種表示方法(notation),也就是記法 :(按照時間順序 發展歷程)
- 符號與幅值
- 反碼
- 補碼
- 開發這三個抽象的玩意兒只是因爲解決
- 正數 與 負數的表示問題
- 正數 負數的運算問題(主要是加減 因爲其他運算從加減衍生出來)
- 下面我們來看看 這三個裝逼晦澀的東西到底有多簡單 不要慫 往下走
符號與拓展
我們想一下 區分正負數 最好的辦法就是加一個符號位
這就是 “符號與幅值表示法” 英文是sign and magnitude
- sign 符號
- magnitude 幅值
這樣的話 那8-bits 位寬舉例 符號位0爲正數 1爲負數:
- 0000 0011 = 310 — 10進制的3
- 1000 0011 = -3 10 – 10進制的-3
- 也就1~7位是幅值 第八位是符號位
這種方法比較直觀 但是沒法用
你試着加減一下 就發現需要很多工作要做
計算機性能就被拖累在每一次加減運算了
於是我們的先輩想了另一種方法:反碼
反碼
反碼的思路來源於 進行減運算的時候 一旦借位 前面的所有0 都變成1 1變成0
比如 我拿0(其實是正零 後面再說 現在來個劇透)舉例
- 010 - 110
- 0000 0000 - 0000 0001 需要借位 於是就
- 1111 1110 = -110
發現沒有 這個計算機可以直接算 不需要像第一種方法有多餘的步驟
當然 計算機將所有運算都化爲 加法運算 所以:
實際上運算是這樣的:
- 010 + (-1)10
- 0000 0000 + 1111 1110
- 1111 1110 = -110
-1 就是 1 按位取反後的結果 這就是“反碼” 或者說“取x的反碼” 的含義 :按位取反
由此 我們知道 反碼錶示法中(8位):
- 最大的正數 0111 1111
- 絕對值最大的負數 1000 0000
- 絕對值最小的負數 1111 1111 = “負零” 010
- 絕對值最小的正數 0000 0000 = “正零” 010
不要想當然 第1~7位不再是“幅值” ,也就不是通過位權簡單加起來完事了的
但是反碼帶來很大的問題
- 沒有解決第一種方法的 兩個零問題(正零 負零)
- 運算不方便(你可以試試)
你發現 數的符號是確定的 但是如何進行二進制轉十進制 就變得比較麻煩
因爲第1~7位不再是“幅值” 需要補一個1纔行
這就是下一輪的改革:補碼
補碼
上過課的同學都知道 補碼錶示法中
我要想獲得一個數的負數(1與-1) 只需要先求那個數的反碼 再加1就行
其實實質上就是上面所說的 因爲反碼不靠譜 計算機識別數的大小很麻煩 而且還有雙零問題
所以我們加個1
僅此而已
這樣操作以後 我們發現 識別數字大小變的簡單 自然轉別的進制也變得簡單:
例如:
注意 符號位用的是負號
符號拓展
這裏針對補碼錶示法 也間接說明補碼的好處
所謂符號拓展 就是16位數轉爲32位(比自己位寬大的)的時候的運算套路
很明顯 多餘的位 也就17位到32位 都是沒有信息 自動補足的
我們看個例子:
這種有點無腦其實 直接用符號位補足第17~32位
原理就是 減法借位 前面的0都變成1 1都變成1 之前說了
總結 ´◡`
所謂 補碼 反碼 符號與幅值 就是三個解決正負數表示 運算的三個方法
名稱 | 實質 | 獲取負數形式方法 |
---|---|---|
符號與幅值(sign and magnitude) | 解決方法ver1.0 | 把某一位作爲符號位 然後符號位取反 |
反碼(one’s complement) | 解決方法ver2.0 | 按位取反 |
補碼(two’s complement) | 解決方法ver3.0 | 按位取反 再加1 |
最後 可能你還感興趣別的內容 這裏來幾個傳送:
-
想學習數據庫嘛? 不妨從MySQL入手
MySQL專欄 -
python這麼火 想要深入學習python 玩一下簡單的應用嘛?可以看我專欄 還在持續更新中哦:
python應用 -
小孩子才做選擇 大人全都要!對後端感興趣嗎?收下它吧:)
手把手帶你學後端(服務端)
目前在Django框架學習階段