2018-2019-1 20189206 《深刻理解計算機系統》第二章學習筆記

2018-2019-1 20189206 《深刻理解計算機系統》第五週學習總結

教材學習內容總結

本章主要研究三種重要的數字表示,分別是無符號編碼、補碼編碼和浮點數編碼。其中,無符號編碼表示大於或等於零的數字,補碼編碼用來表示有符號整數,浮點數編碼是科學計數法的以2爲基數的版本。linux

第二章 信息的表示和處理

信息存儲的方式

  1. 最小可尋址的內存單位————8位的塊,也稱爲字節
  2. 機器級程序將內存視爲一個很是大的數組,稱爲虛擬內存
  3. 內存的每一個字節都由惟一的數字來表示,稱爲地址

十六進制表示方式

  1. 一個字節的
    對應的二進制表示爲 \(00000000_2 至 11111111_2\)
    對應的十進制表示爲 \(0_{10} 至 255_{10}\)
    對應的十六進制表示爲 \(00_{16} 至 FF_{16}\)(以0x或者0X開頭的數字爲十六進制表示)
  2. 特殊的轉換方法數組

    當值x是2的非負整數的n次冪時即 \[x=2^n\] 能夠將x寫成1後面加n個0的形式。
    當n表示爲 n=i+4j 時(0<=i<=3),x對應的十六進制數字能夠寫成一、二、四、8後面跟J個0
    例如: \[ 512 = 2^9 \] 知 n=1+2*4 故2048對應的16進制是 0x200函數

字數據大小

  1. 每一個計算機都有一個字長,用來指明指針數據的標稱大小。 字長決定的最重要的系統參數就是虛擬地址空間的最大大小。對於一個字長爲w的機器,虛擬地址的範圍爲\[ 0 至 2^w -1 \]程序最多訪問2^w個字節。
  2. 多字節對象被存儲爲連續的字節序列,對象的地址爲使用字節中最小地址
    • 大端法:最高有效字節存儲在前面(即先存儲最高有效字節)
    • 小端法:最低有效字節存儲在前面(先存儲最低有效字節)
    • 假設0x01234567
      • 大端法存儲爲 01 23 45 67 (地址從左至右增大)
      • 小端法存儲爲 67 45 23 01 (地址從左至右增大)
  3. linux32 Windows和linux64 均爲小端機器,能夠記爲閱讀順序和存儲順序相反。

下面show_bytes函數的做用是打印出每一個以十六進制表示的字節,其中輸入是一個字節序列的地址。學習

void show_bytes(byte_pointer start,size_t len)
{
    size_t i;
    for(i=0;i<len;i++)
    {
        printf("%.2x",start[i]);
    }
    printf("\n");
}

void show_int(int x)
{
    show_bytes((byte_pointer)&x,sizeof(int));
}

實現的功能就是輸出int型每一個字節對應的十六進制表示。優化

布爾代數

布爾運算     邏輯運算    命題邏輯
       ~          NOT        ┐
       &          AND        ∧
       |          OR         ∨
       ∧         異或        ⊕
  • 位級運算的經常使用用法是實現掩碼運算,掩碼錶示從一個數中選出的位的集和。
    x & 0xFF 獲得的結果就是x最低有效字節組成的值,其他字節被置0,以後表達式~0 獲得的結果就是全爲1 的掩碼。

【注】注意區分C語言中的邏輯運算與位級運算編碼

C語言的邏輯運算是|| &&和!,分別對應命題邏輯中的OR、AND和NOT運算。邏輯運算認爲全部的非零值都爲真,參數零表示假,運算結果只由0和1。

邏輯運算中若是第一個參數求值就能肯定表達式的值,邏輯運算不會對第二個參數求值spa

位移運算

  • 位移運算分爲左移和右移
    • 左移 X向左移,丟棄最高的k位,並在右端補0
    • 右移 X向右移,丟棄最低的k位
      • 算數右移 在左端補k個最高有效位的值
      • 邏輯右移 在左端補0

幾乎全部的編譯器/機器組合都會對有符號數使用算數右移,而對於無符號數,右移必須是邏輯右移。操作系統

整數表示

無符號數只能表示非負數,而補碼編碼可以表示負數、0和正數。指針

  • 無符號數的編碼code

    • 無符號數的定義
      對於向量 \[ \vec{x} = [x_{w-1},x_{w-2},\cdots,x_0] \]

      \[B2U_w (\vec{x}) = \sum_{i=0}^{w-1}x_i2^i\]

    • 無符號數所能表示的值的範圍
      [0 0 …… 0] 到 [1 1 …… 1]即
      \[UMax_w = \sum_{i=0}^{w-1}2^i = 2^w-1\]

    • 無符號編碼的惟一性
      函數B2U是一個雙射,將每個長度爲w的位向量,映射爲0~2^w-1之間的惟一一個值,這種映射是一一對應的關係,便可以反向操做。

  • 補碼編碼
    最多見的有符號數的計算機表示方式就是補碼形式,這種形式下,將字的最高有效位解釋爲負權。

    • 補碼編碼的定義

    對於向量 \[ \vec{x} = [x_{w-1},x_{w-2},\cdots,x_0] \]

    \[B2T_w (\vec{x}) = -x_{w-1}2^{w-1} + \sum_{i=0}^{w-1}x_i2^i\]

    最高有效位稱爲符號位,符號位爲1時,表示值爲負數;符號值爲0時,值爲非負。

    • 補碼所能表示的範圍

    它能表示的最小值是[1 0 …… 0] 其整數值爲 \[TMin_w = -2^{w-1} \]
    最大值爲[0 1 …… 1] 其整數值爲\[TMax_w = \sum_{i=0}^{w-1}2^i = 2^w-1\]

    • 補碼有着與無符號數相同的雙射函數
    • 最大無符號數恰好比補碼的最大值的兩倍大一\[UMax_w=2TMax_w + 1 \]

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

  • 強制類型轉換的結果保持位不變,只是改變了解釋這些位的方式。處理一樣字長的有符號數和無符號數之間的轉換通常規則是:數值可能會改變,可是位模式不變

  • 補碼轉換爲無符號數

對知足\[TMin_w\leq x \leq TMax_w \]的x有:
\[T2U_w(x) =\begin{cases} x+2^w & x <0 \\\ x & x \geq 0 \end{cases}\]

從以上表達式能夠看出,將一個有符號數轉爲它相應的無符號數時,負數就被轉換成了大的整數,非負數則會保持不變。

  • 無符號數轉換爲補碼

對知足\[0 \leq u \leq UMax_w \]的x有:
\[U2T_w(u) =\begin{cases} u & x \leq TMax_w \\\ u-2^w & u>TMax_w \end{cases}\]

從以上表達式能夠看出,講一個無符號數轉換爲補碼時,U2T把大於2^w-1的數轉化成了負數。

從上述兩個公式能夠看出,對於在範圍\[ 0 \leq x \leq TMax_w \]的範圍內的數字有着相同的補碼和無符號數表示。對於這個範圍之外的數須要加上或者減去2^w

  • C語言中,當執行一個運算時,它的一個運算數是有符號的,另外一個運算數是無符號的,那麼C語言會將有符號數強制類型轉換爲無符號數,並假設這兩個數都是非負的。

擴展一個數字位的表示

  1. 將無符號數轉換爲一個更大的數據類型——零擴展
  2. 將補碼轉換爲一個更大的數據類型——符號擴展(添加最高有效位的值)

截斷數字

  1. 截斷無符號數

\[\vec{x} = [x_{w-1},x_{w-2},\cdots,x_0]\] 現截斷該位向量k位的結果是\[x' = x mod 2^k\]

  1. 截斷補碼數值
    \[\vec{x} = [x_{w-1},x_{w-2},\cdots,x_0]\] 現截斷該位向量k位的結果是\[x' = U2T_k(x mod 2^k)\]即把最高位的權重從正變爲負。

整數運算

  • 無符號加法
    定義無符號數加法,該操做是把整數和x+y截斷爲w位獲得的結果,再把這個結果看做是一個無符號數。能夠被看做是一種形式的模運算
    對於x、y知足\[ 0 \leq x,y<2^w \]有:
    \[x + y =\begin{cases} x+y & x+y \leq 2^w \\\ x+y-2^w & 2^w \leq x+y <2^{w+1} \end{cases}\]

當x+y的結果s小於x或者小於y的時候,能夠斷定無符號數的加法出現了溢出。

  • 無符號數求反

模數加法造成了一個阿貝爾羣,對於每一個x值一定有有一個加法逆元。
對於知足\[ 0 \leq x <2^w \]的任意x值,其無符號加法逆元爲
\[- x =\begin{cases} x & x=0 \\\ 2^w-x & x>0 \end{cases}\]

  • 補碼加法
    對於知足\[-2^{w-1} \leq x,y \leq 2^{w-1}-1 \]的整數x和y 有
    \[x + y =\begin{cases} x+y-2^w & 2^{w-1} \leq x+y & 正溢出 \\\ x+y & -2^{w-1} \leq x+y <2^{w-1} &正常\\\ x+y+2^w & x+y<-2^{w-1} & 負溢出 \end{cases}\]

  • 補碼的非
    對於知足\[ TMin\_w \leq x <TMin\_w \]的任意x值,其補碼的非爲
    \[- x =\begin{cases} TMin\_w & x=TMin\_w \\\ -x & x>TMin\_w \end{cases}\]

  • 無符號和補碼乘法
    將一個數截斷w就等價於計算該值的模2^w
    對於無符號和補碼乘法來講,乘法運算的位級表示都是同樣的。

  • 乘以常數

因爲在大多數機器上,整數乘法的指令須要10個或者更多的時鐘週期,其餘整數運算只須要1個時鐘週期。編譯器使用了優化,試着用位移和加法的運算組合代替乘以常數因子的乘法。
原理: 設x的位模式爲 \([x_{w-1},x_{w-2},\cdots,x_0]\)表示無符號整數,那麼對於任何$k \leq 0 $都認爲 \([x_{w-1},x_{w-2},\cdots,x_0,0,0,\cdots,0]\) 給出了 \(x*2^k\) 的w+k位的無符號表示,右邊增長了k個0。
能夠看出,左移一個數值至關於執行一個與2的冪相乘的無符號乘法

例如:一個程序包含表達式 x*14 利用 $14 =2^3+2^2+2^1 $ 能夠將該乘法重寫(x<<3)+(x<<2)+(x<<1),將一個乘法替換爲位移和兩個加法。
或者利用 $14 =2^4-2^1 $ 重寫成 (x<<4)-(x<<1)

  • 除以2的冪
    • 除以2的冪的無符號除法
      假設有無符號數值x和k,且 $0 \leq k <w $ 則表達式 x>>k 產生結果\(\lfloor x/2^k \rfloor\)
    • 除以2的冪的補碼除法
      假設有補碼數值x和無符號數值k,且 $0 \leq k <w $ 則表達式執行算術位移 x>>k 產生結果\(\lfloor x/2^k \rfloor\)

浮點數

  • 二進制小數
    表示方法:$ b_m b_{m-1} \cdots b_1 b_0.b_{-1} b_{-2} \cdots b_{-n} $
    這個表達描述的定義以下:
    \[b = \sum_{i=-n}^{m}2^i*d_i \]

  • IEEE浮點表示
    • 浮點標準用\[ V= (-1)^s * M * 2^E \] 來表示一個數
      • 符號:s決定了這個數是負數(s=1)仍是正數(s=0)
      • 尾數:M是一個二進制小數,範圍是1~2-ε 或者 0~1-ε
      • 階碼:E的做用是對浮點數加權,這個權重是2的E次冪
    • 將浮點數的位表示劃分爲3個字段,分別對這些值編碼
      • 一個單獨的符號位s
      • k位的階碼字段\(exp=e_{k-1} \cdots e_1 e_0\)編碼階碼E
      • n位的小數字段$frac=f_{n-1} \cdots f_1 f_0 $編碼尾數M
    • 規格化的值
      • exp的位模式不會全爲0或全爲1 階碼字段被表示爲以偏置形式表示的有符號整數。E= e-bias e爲無符號數 \(bias=2^{k-1}-bais\)
      • 小數字段frac,尾數定義爲M=1+f
    • 非規格化的值
      • 階碼E全爲0時是非規格化的形式,此時 E=1-Bias 尾數值M=f
    • 特殊值
      • 階碼全爲1時,獲得的值表示無窮

【注】浮點運算只由有限的範圍和精度,而且不遵照結合律。

總結

本章重點在於用數學公式準肯定義出計算機中使用的幾種數據類型,內容不少,須要好好總結和複習。經過直接操做數字級的位表示,獲得了幾種算數運算的方式。針對不一樣的機器,變量類型存儲的大小也不一樣、存儲方式不一樣,爲了能使編寫的程序在所有範圍內正確工做,能夠實現跨越不一樣的機器、操做系統和編譯器的組合,對於這種數學原理的學習是十分重要的。 第二章主要從信息存儲的方式、整數表的方法(無符號編碼、補碼編碼)以及相關操做、整數運算(無符號運算、補碼運算)、浮點數(兩種表示方式)等方面介紹了數據的存儲表示方式,進行計算的結果等內容。

相關文章
相關標籤/搜索