計算機的運算方法



計算機的運算方法

無符號數

計算機中的數存放在寄存器中,一般將寄存器的位數稱爲機器字長, 你們說的無符號數其實就是不區分正負號的數,換句話說,就是沒負數,全是正數,你們知道,計算機中的數是以0-1存儲的, 假如咱們的寄存器16位, 無符號數表示的範圍就是0~65535 (2^64=65536), 有符號就是分正負數,總數65536就被分紅兩半,一半正數,通常負數,範圍就是 -32768~32767框架

有符號數

有符號數,就是正負數同時存在, 人們當然能區分開整正負數,計算機怎麼區分呢?學習

前面說了,計算機只認識01這樣的數,因而人們規定 0表示正數, 1表示負數, 因而這樣符號就被數字化了, 而且規定將其放在真實值前面, 因而有符號數就誕生了編碼

真值和機器數

如上圖,按照計算機存數數據的特性將符號數字化, 數字化後的編碼方式獲得的結果稱爲機器數, 將帶有+-符號的數字稱爲真值設計

既然如今將有符號數數字化後,新的問題來了,當這些機器數之間須要進行運算時, 符號位怎麼辦? 符號位可否參加機器數之間的運算呢? 若是說,須要參加運算又須要哪些處理才能消除符號位對計算結果的影響呢? 這一連串問題就引出了符號位和數值位所構成的編碼: 原碼 , 補碼 , 反碼 , 移碼 3d

其實在學習的過程當中該一直問本身,本身在幹什麼??? 就好比如今,我在前面大概說了說計算機是如何表示數字的,因而認識了機器碼,機器碼之間須要進行運算於爲了設計出使機器碼運算的方式,人們對機器碼進行不一樣的變形編碼,獲得了,原碼 , 補碼, 反碼 , 移碼等, 下面看一下這幾種編碼的由來,以及他們對實現機器碼的可計算的貢獻code

原碼

原碼是機器碼最簡單的一種變形,一樣的它的符號位0表示正數,1表示負數。 數值位就是真值的絕對值blog

人們爲了書寫方便已經區分小數和整數,在符號位和數值位之間使用逗號分隔數學

整數的原碼

整數原碼

舉個例子:table

x= +1110, 那麼它的原碼就是 0,1110
x= -1110, 原碼=1,1110

小數的原碼

小數原碼

舉個例子class

x= 0.1101 ,  那麼它的原碼就是      0.1101
x= -0.1101,  原碼=1 - (-0.1101) = 1.1101

看上面的原碼計算方式,顯然機器碼很容易就轉成原碼,可是想一想若是用原碼進行數值運算的話就會帶來不少麻煩,咱們得先判斷兩個機器數絕對值的大小而後用大的減去小的,最終的符號再按照絕對值大的算, 並且咱們須要設計兩套運算流程,一套給加法用,一套給減法用, 可是前輩們很智慧,由於人們找到了一種方式,找到了一個正數去替換原來減數位置的負數,相似像下面這樣,實現了在計算機中僅僅設計一套加法器就實現加減法的運算

5-3=2
5+(-3)=2

上述方法的實現就依賴於下面的補碼

補碼

補碼的概念和補數的概念很像, 好比如今時鐘六點了,咱們想讓它指向三點,因而咱們能夠往回轉3(6-3=3)圈時針能回退到3點,也能夠往前轉9圈(6+9=15),能夠前進到三點, 對時鐘來講往順時針仍是逆時針的過程不同,可是對咱們來講結果是同樣的,都是三點了

這個過程就相似於,找到一個正數,讓這個正數代替負數去參加運算,使用加法運算器也能獲得正確的結果

時鐘旋轉一圈12小時,在這12小時中是不被顯示且自動丟失的,也就是說 15-3=3 點, 因而咱們能夠說,其實對時鐘來講, -3 +9 的做用實際上是一致的,結果都是三點, 在數學上咱們將12稱爲模 ,寫成mod 12 , 咱們管9 稱爲是 -3以12爲模的補數

因而咱們得知,只要咱們肯定了模,咱們就能求出這個數對這個模的地位相同的補數,或者說當咱們想將已知的負數轉換成能夠替換他的正數的話,藉助模就能夠完成

如何利用模求補數呢?

  • 正數的補數是它自己
  • 負數能夠用它的正補數等價替換
  • 負數的補數= 模+負數自己

如何進行求模示例:

-3    全等於 +7    (mod10)
+7    全等於 +7    (mod10)
-3    全等於 +97   (mod100)

-1011 全等於 +0101    (mod2^4)
2^4=1 0 0 0 0
-     1 0 1 1
---------------
      0 1 0 1
   
+0101  全等於 +0101   (mod2^4)

小數的mod = 2
+0.1001 全等於 +0.1001  (mod2)

-0.1001 全等於 +1.0111  (mod2)
 1 0.0 0 0 0
-  0.1 0 0 1
--------------
   1.0 1 1 1

求補碼的公式

正補公式

求負數補數的示例

正補示例

其實你們能夠看一下,對負數的公式來講,公式中的n就是負數的位數, -1101 一共四位, n=4, 可是取的是n+1位, 換句話說是用一個比原負數多兩位的數加上這個負數, 多出來一個符號位, 最後的結果中別忘了用 逗號分隔符號位和數值位, 固然這是爲了方便咱們本身看,讓人們一眼看去知道最開始的1是個符號位,後面的數纔是 想求的補數結果

小數求補碼的公式

小數補碼公式

舉個例子: 求 -0.0110 的補碼

求小數的補碼示例

此外, +0 -0的補碼都是 0

從上面的討論咱們知道,之因此想引入補碼是爲了消除減法運算,即將一個負數轉換成它的正數補碼,可是根據補碼的定義,你們能夠看到上面的兩個例子,在產生補碼的過程當中又出現了減法運算,怎麼辦呢?

因而咱們這樣求補碼: 先求原碼, 而後變換這個原碼獲得補碼, 怎麼變換呢? 就是將除了 符號位的原碼其它爲取反 以後再加1

舉個例子: 上面的就用 -1101 來講, 以下:

從原碼求補碼

因而看到這裏咱們完全知道了,只爲計算機設計一個加法器是徹底ok的,下文會介紹如何運算

反碼

經過上面的運算咱們知道下面的運算規則

原碼(符號位,數值位) => 除符號位外其餘位取反  = 反碼
反碼+1 = 補碼
補碼-1 = 反碼

由此可知,其實這個反碼就是原碼和補碼雙方轉換時的中間狀態

小結

  • 原碼,反碼,補碼的最高位都是符號位, 符號位和數值位之間使用.或者逗號分隔(小數用點, 整數用逗號)
  • 真值爲整數時, 原碼,反碼,補碼的表示形式是相同的
  • 雖然真值爲負數時,原碼.反碼補碼各不相同,可是最高位的符號爲都是1, 而且原碼求反+1=補碼 , 原碼每位求反=反碼

移碼

真值轉換成補碼後,因爲符號位和數值位是一塊兒進行編碼的,所以人們很難分清補碼之間的大小

就像下面這樣

十進制的21  對應二進制爲+10101  補碼爲 0,10101
十進制的-21  對應二進制爲-10101  補碼爲 1,01011
十進制的31  對應二進制爲 +11111  補碼爲 0,11111
十進制的-31  對應二進制爲-11111  補碼爲 1,00001

直觀上看他們的大小是 101011>010101 100001>011111 而實際上偏偏相反

因而咱們這樣, 在每個真值的基礎上加上一個2^n , 狀況就發生了變化

+10101  加上2^5  得 110101
-10101  加上2^5  得 001011
+11111  加上2^5  得 111111
-11111  加上2^5  得 000001

這樣的話不須要藉助補碼,六位代碼自己就能看到出真值的大小

更進一步,經過觀察能夠發現,其實一個數的補碼和移碼之間就差一個符號位,換句話說,若是咱們將補碼的符號位從0換爲1,或者從1換成0獲得的就是它的移碼, 在這基礎上比較大小獲得的結果是準確的

此外正負零的移碼的同樣的

移位運算

計算機中的機器數的字長每每是固定的,當機器數左移n位或者是又移n位時,勢必會卻是另一邊出現空位,那麼在出現空位的位置究竟是補充1仍是填充0呢? 這取決於機器數是有符號仍是無符號,其中有符號的機器數採起的位移稱爲算數位移,無符號的惟一稱爲邏輯位移

算數位移的移位規則

真值 碼制 補填代碼
正數 原碼,補碼,反碼 0
負數 原碼 0
負數 原碼 左移添0
負數 補碼 右移添1
負數 反碼 1

不管是正數仍是負數,移位後的符號位都是不變的

舉幾個例子

機器數        十進制
移位前 : 0,0011010      +26
左移1位: 0,0110100      +52
右移1位: 0,0001101      +13

左移一位,除符號位外原來的最高位被移走了,右邊空出的1位用0補全,可是高位丟失了其實獲得的就是錯誤的結果,可是這個錯誤的結果剛好是原值的2倍,並且惟一運算速度還快,所以不少框架的底層都青睞使用這個位移運算的特性

每次右移時,最右邊的數就會丟失,精度收到影響

左移一位至關於乘以2,右移1位至關於除以2

邏輯位移的移位規則

邏輯左移,高位丟失,低位填0, 邏輯右移,低位丟失,高位補0

加法與減法運算

回到一開始話題,計算機的運算方法,前面經過補碼的介紹咱們知道了只設計一套加法器實際上是可行的,下面具體看一下是如何進行運算的

即 A-B = A + (-B)

補碼的加法公式

整數:  [A]補 + [B]補 = [A+B]補  (mod 2^n+1)
小數:  [A]補 + [B]補 = [A+B]補  (mod 2)

對於減法來講

整數:  [A-B]補 = [A]+[-B]補  (mod 2^n+1)
小數:  [A-B]補 = [A]+[-B]補  (mod 2)

最後看一個例子: 看看計算機如何將減法轉換成加法並攜帶符號位運行得出正確結果

假設機器8位(含一位符號位),若A=+15 B=+24, 讓咱們求 [A-B]補 ,並還原真值

A=+15 = +0001111  (算上+號一共八位)           
b=+24 = +0011000  (算上+號一共八位)

A和B都是整數,因此他們的補碼就是原碼自己:
[A]補 = 0,0001111
[B]補 = 0,0011000

[-B]原碼 = 1,0011000
[-B]反碼 = 1,1100111  ( 除符號位取反獲得反碼:)
[-B]補   = 1,1101000   (由反碼+1獲得)

[A-B]補 = [A]補 + [-B]補  
        = 0,0001111 + 1,1101000
        = 1,1110111
 
那麼 A-B = 啥呢? 反着換回去
1,1110111 
1,1110110  (末位減1再取反)
1,0001001 = -0001001 = -9
相關文章
相關標籤/搜索