1. 程式人生 > >深入理解計算機系統 第二章資訊的表示和儲存、

深入理解計算機系統 第二章資訊的表示和儲存、

引言:

這一章我們研究在計算機上如何表示資料和其他型別資料的基本屬性,以及計算機對這些資料執行操作的屬性。在整數運算中,重點描述無符號數和數的補碼所表示的特性;而對於IEEE標準的浮點型資料,一是它是如何表示資料的,二是浮點運算的數學形式。

三種常見的資料型別:整數分為無符號數和有符號數。無符號數,表示大於或者等於零的數,基於傳統的二進位制表示法;有符號數表示正數或負數,通常用補碼來表示,浮點數多為小數型別的值。
現代計算機資訊的儲存和表示通過二值訊號0和1來表示,最小的單位為位,bit。單個的位並沒有什麼意義,但是將多個位按照一定的順序連線起來,就能夠表示有限集合的元素。 

2.1資訊儲存,主要講計算機如何儲存二進位制的資料,例如小端法和大端法這兩種儲存方式,同時還講了一些布林代數運算的基礎,這就是我們熟悉的位運算和位移運算(Bitwise>
> & Bit Shift)以及邏輯運算。
> 2.2整數表示,主要說明有符號數和無符號數那些實現原理,例如有符號數會涉及到補碼(Two’s Complement)處理。
>  2.3整數運算,則具體描述計算機如何給二進位制資料做加減乘除運算,這裡面還會繼續分別講解有符號數和無符號數的處理。
>  2.4浮點數,則單獨地講解計算機如何表示有小數點的資料,並如何做運算,但最重要的是浮點數精度限制問題的講解。


 2.1 資訊儲存

計算機中可定址的最小地址單元為位元組,儲存器的每個位元組都由一個唯一的數字來標識,稱為它的地址,所有可能地址的集合稱為虛擬地址空間,包括隨機訪問儲存器,快閃記憶體,內盤儲存器等。

  • 十六進位制表示

  十六進位制數字:0 – F,例子:173A4C

 二進位制數字:0 – 1,例子:0001 0111 0011 1010 0100 1100

 相互轉換:十進位制→ 十六進位制:Mod(10,16)(倒序排列)

  • 字資料大小  

  字長決定的最重要的系統引數就是虛擬地址空間的最大大小。對於一個字長為ω位的機器而言,虛擬地址的範圍就是0 ~ 2^ω - 1,程式最多訪問2^ω個位元組。

  • 定址和位元組順序:

    多位元組物件被儲存為連續的位元組序列,物件的地址為所用位元組最小的地址。

    最低有效位元組在最前面的方式,稱為小端法。
    最高有效位元組在最前面的方式,稱為大端法。

  • 字串表示:    

               每個字元用某個標準編碼來表示,常見的為ASCII字元碼。

  • 布林運算

              ~非,&與,|或,^異或,位運算。

  • 邏輯運算

          邏輯運算認為所有非0引數表示TRUE,0表示FALSE。對應OR(||)、AND(&&)和NOT(!)。如果第一個引數求值就能確定表示式的結果,那麼邏輯運算子就不會對第二個引數求值。    

  • 位級運算

       左移,x<<k,丟棄最高的k位,右端補k個零。右移分為邏輯右移和算術右移。邏輯右移在左端補0,算術右移在左端補最高位,在有符號的整數(最高位為1)移位時有區別。編譯器預設為算術右移。當一次移位的k大於數的位數w時,C語言標準是移動k%w。

 2.2 整數表示

  • 整數分為無符號數和有符號數。

無符號數,表示大於或者等於零的數,基於傳統的二進位制表示法,如3表示為0011;

有符號數表示正數或負數,通常用補碼來表示,有符號整數用補碼編碼,最高位為符號位,1表示負數,0為非負。負數的補碼為原碼的反碼加1,正數的補碼為本身。補碼錶示的範圍,以4位為例,1000表示最小(-8),最大為0111(7),1111表示-1,0000表示0。

  • 有符號數和無符號數之間的轉換

C語言允許在各種不同的數字資料型別之間做強制轉換。

強制型別轉換的結果保持位值不變,只是改變了解釋這些位的方式。

執行一個運算的時候,如果它的一個運算數是有符號的而另一個是無符號的,那麼C語言會隱式的將有符號數強制型別轉換為無符號數,並假設兩個數都是非負的,來執行運算。

  • 擴充套件一個數字的位表示

要將一個無符號數轉換為一個更大的資料型別,只需要簡單的在表示的開頭新增0,這種運算被稱為零擴充套件。

要將一個補碼數字轉換為一個更大的資料型別,可以執行一個符號擴充套件,在表示中新增最高有效位的值

 2.3. 整數運算

無符號加法:溢位直接去除高位。   
有符號加法:當做無符號數進行加法,溢位直接截斷。
有符號的非:-x=~x+1,即等於按位取反再加1.
有符號數的乘法:x*y=(x的補碼*y的補碼)的補碼
整數乘以常數:用移位和加法以及減小來代替乘法,無論x是無符號的還是有符號的,其計算結果一致。
整數除以常數:思路與乘法一致。有符號整數移位在小於0時會出現問題,當x<0時,x>>k的結果是x/(2^k)的向下取整,例如-12340>>4結果為-772,然而-12340/16應該是-771,這時C語言對其進行修改:(x<0?x+(1<<k)-1:x)>>k在x<0的情況下,加上(1<<k)-1的偏置量。

 2.4. 浮點數

符號位s:複數s=1,正數s=0

尾數M:是一個二進位制小數

階碼E:對浮點數加權,權重為2,可以為負數

規格化的值

解碼欄位被解釋為偏置形式表示的有符號整數。階碼的值是E = e - Bias,其中e是無符號數,而Bias是一個等於2^(k-1) - 1的偏置值。

小數子段frac被解釋為描述小數值f,其中0 ≤ f < 1,二進位制小數在最高有效為的左邊。尾數定義為M = 1 + f。這種方式也叫做隱含的以1開頭的表示。

非規格化的值

階碼值是E = 1 - Bias,而尾數的值是M = f,也就是小數字段的值,不包含隱含的開頭的1。

非規格化數的另外一個功能是表示那些非常接近於0.0的數。它們提供了一種屬性,稱為逐漸溢位,其中,可能的數值分佈均勻的接近於0.0。

浮點數的舍入: 預設為向偶數舍入法。

在C語言中,有兩種浮點數float和double,舍入方法為向偶數舍入,

 整數和浮點數之間轉換規則:
int轉float不會溢位,可能被舍入。
double轉float有可能溢位,可能被舍入。
float或double轉int會向0舍入,例如1.9轉為1,-1.9轉為-1.可能溢位。