微機原理(一)補碼 反碼 符號與幅值 符號拓展

前言 ´・ᴗ・`

  • 二進制數有常見的三種表示方法(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框架學習階段

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章