我的C筆記(一)

計算機內數據的存儲是以二進制數的補碼形式存在的。

那麼什麼是補碼呢?

這裏要涉及到二進制數的原碼、反碼、補碼等存儲方式的概念。

      1. 機器編碼

機器編碼有原碼、反碼、補碼、移碼、階碼等。

        1. 原碼
          1. 原碼概念

計算機中所有的二進制數均用0、1編碼表示,數字的正、負也不例外,如果一個機器數字長是n的話,約定最左邊1位作爲符號位,其餘n-1位用於表示數值。在符號位上,用0表示正,用1表示負。數值位表示真值的絕對值。凡不足n-1位的,小數在最低位右邊增加0;整數則在數值位的最高位(不是符號位)左邊增加0,補足n-1爲。這種計算機的編碼形式叫做原碼

原碼的表示形式:符號位+二進制數值

例如十進制數12,它的二進制原碼爲[0000 1100],最高位0表示符號+(正)。

有符號的二進制編碼如下圖所示:

 

圖 1 8bit機器

例如在8bit的機器內,小數和整數的表示:

小數:[+0.1011]原=0.1011000,補足8位:

0

1

0

1

1

0

0

0

 

  [-0.1011]原=1.1011000,補足8位:

1

1

0

1

1

0

0

0

 

整數:[+1011]原=00001011,補足8位:

0

0

0

0

1

0

1

1

 

  [-1011]原=10001011,補足8位:

1

0

0

0

1

0

1

1

 

代碼中的小數點只是在書寫時爲了清晰可見,在機器中並不出現。

          1. 原碼的特徵

◇最高位0表示,1表示。其餘二進制數是該數字的絕對值的二進制位。

 

◇原碼簡單易懂,接近人的思維。

例如:我們用8位二進制表示一個數,+11的原碼爲00001011,-11的原碼就是10001011,這個很好理解。

 

◇加、減運算複雜,相減時,被減數不夠減時,需要向高位借位。原碼的符號位不能直接參與運算。

一個字長爲n(即n bit)的機器數能表示不同的數字的個數是固定的:2n個,n=8時,2n=256。如果用來表示有符號數,那麼取值範圍是-2n-1~+2n-1。n=8時這個範圍即是-128~127。但是在不考慮數的的正負時,就不需要用1位二進制數來表示符號位,n位機器數全部用來表示數值,這時表示數的取值範圍是0~2n-1,n=8時的範圍就是0~255。沒有符號位的數,稱爲無符號數。

 

◇存在四種運算,增加CPU的複雜度。

 

◇0的表示不唯一,有+0和-0之分。

        1. 反碼

反碼是數值存儲的一種,多應用於系統環境設置,如linux平臺的目錄和文件的默認權限的設置umask,就是使用反碼原理。

反碼運算不方便,也沒有在計算機中得以應用。

反碼錶示法規定

◇正數的反碼與其原碼相同

[01010]原=[01010]反

 

◇負數的反碼是對其絕對值正數的原碼逐位取反,取反時包含符號位。

例如,對二進制數10010的原碼求反碼:

[10010]原碼

=[00010]取正(1.先對原碼取其絕對值。)

=[11101]取反(2.對得到的絕對值取反,取反時包括符號位。)

注意:其實,求負數的反碼也可以說是負數的原碼符號位不動,其餘取反。

負數原碼的反碼 = ~|負數|,~爲取反的意思。

如下:

如:原碼10010的反碼可以這樣求得:

[10010]原碼=[11101]反碼----符號位不動,其餘逐位取反。

 

那麼原碼(10010)2的反碼(11101)2就是表示十進制數(-2)10。反碼並不是十進制數在計算機中的二進制表現形式,在計算機中表示的二進制數是補碼。那麼什麼是補碼呢?接着往下看。

        1. 移碼

表示數值平移n位,n稱爲移碼量。移碼主要表示浮點數的階碼的存儲。

        1. 補碼
          1. 補碼的概念

在計算機系統中,二進制數值一律用補碼來表示和存儲。

補碼的設計目的是:

◇使符號位能與有效值部分一起參加運算,從而簡化運算規則。

◇補碼與原碼相互轉換,其運算過程是相同的,不需要額外的硬件電路。

◇使減法運算轉換爲加法運算,進一步簡化計算機中運算器的線路設計,所有這些轉換都是在計算機的最底層進行的。

          1. 補碼錶示法規定

補碼是由原碼轉化而來,那麼轉化規則是:

◇正數的補碼與其原碼相同。

正數的補碼 = 正數的原碼

(10)10  =[0000 1010]原

=[0000 1010]補

 

◇負數的補碼是在取其反碼之後加1。

負數的補碼 = 負數原碼的反碼+1

負數原碼的反碼 = ~|負數|

(-10)10 =[1000 1010]原

=[1111 0101]反+[0000 0001]即1

=[1111 0110]補

 

例題:把十進制(10)10和(-10)10轉爲二進制補碼錶示。

1).如果十進制數爲,如(10)10,那麼:

(10)10=[0000 1010]原

=[0000 1010]反----對於正數,原碼=反碼

=[0000 1010]補----對於正數,反碼=補碼

所以(10)10 在計算機中的二進制補碼形式爲:(0000 1010)2。

總結:如果十進制數的爲,原碼=補碼。原碼即是二進制數的表示。

 

2).如果十進制數符號爲,如(-10)10,那麼:
(-10)10=[1000 1010]原
   =[1111 0101]反+1

   =[1111 0110]補

 

所以(10)10 在計算機中的二進制補碼形式爲:(1111 0110)2。

總結:如果十進制數爲把原碼取反數,得到反碼,然後把 反碼+1,即是補碼,也就是二進制補碼在計算機中的表示。(一句話:原碼取反+1)

 

3).數據的加減法

如:8 - 9 = -1

計算機中不存在減法,減法是負數的加法。也就是把表示數據的二進制原碼轉爲補碼,進行補碼相加,再把補碼取反。示例過程示例如下:

因爲是補碼運算,所以要對十進制數進行補碼轉換,然後再運算。

8 - 9= 8 + ( -9 )

= [0000 1000]原 + [1000 1001]原

= [0000 1000]反 +( [1111 0110]反+1)

= [0000 1000]補 + [1111 0111]補

= [1111 1111]補----到了這一步,計算機內算是完成了運算,但是我們要看到是十進制數的結果。所以就需要把補碼再轉爲原碼。

以下是還原過程:

設反碼爲X反,那麼

X反 =[1111 1111]補-1

= [1111 1110]反----補碼=反碼+1,那麼反碼=補碼-1,再把反碼取反,得到下一步,即原碼:

= [1000 0001]原----再把二進制原碼轉爲十進制,得到下一步:

= (-1)10

即8-9=-1。

其實,這個運算的發明遠沒有那麼簡單,這裏還涉及到餘數,補數。暫略,後補。

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