北郵CSAPP第二章之整數表示

櫻滿無門發表於2020-12-17

整數表示

  • 主要內容:展示整數的兩種不同表現形式,研究擴充套件或者收縮一個已編碼整數以適應不同長度表示的效果
  • 術語詳見教材
    B:二進位制
    2:to
    U:無符號數
    T:補碼
    w:位數

整型資料型別

  • 為各種不同的資料型別分配的位元組數與32位或64位編譯法有關
  • 根據位元組分配,不同大小能表示的值的範圍是不同的
  • 很值得注意的特點:有符號型別的範圍,負數總是比整數大一。注意,必須考慮這一點,很可能會在程式中造成錯誤

無符號數的編碼

  • 使用位向量表示整個整數資料型別。將其視作二進位制表示的數,就獲得了無符號表示的資料(B2U對映)
  • 無符號數的二進位制表示有一個很重要的屬性:每個介於0~2^w-1之間的數有一個唯一的w位的值編碼 <=> B2U是一個雙射 <=> B2U <-> U2B

補碼編碼

  • 最常見的有符號數的計算機表示方法:補碼形式

  • 補碼的最高位稱之為負權
    B2T = -x(w-1)2^(w-1) + B2U(w-1)

  • 同無符號數編碼一樣,B2T也是一個雙射:對於每個數x,滿足TMinw <= x <= TMaxw,則T2Bw(x)是x唯一的w位模式

  • 值得注意的地方:

  1. 補碼的範圍是不對稱的(再次強調)這將導致補碼運算的特殊屬性與一些細微的錯誤
  2. 無符號整數的最大值剛剛好比補碼的最大值的兩倍多一點 U M a x = 2 T M a x + 1 UMax = 2TMax + 1 UMax=2TMax+1,且 -1與UMax有相同的位表示
  • C檔案中的limits.h中定義了一組常量。限制了編譯器對不同整形資料的取值範圍

  • 對於某些程式來說,用某個確定大小的表示來編碼資料型別非常重要

  • 例如,與網路協議有關的程式,需要使得資料型別與協議指定的資料型別相容

  • C語言確定的只是每種資料型別的最小範圍,而非確定範圍

  • 有符號數的其它表示方法:反碼、原碼
    反碼:最高位是-(2^(w-1) - 1)而非-(2^(w-1)),其它與補碼一致
    原始碼:最高有效位是符號位,其它用來確定正負值

  • 這兩種表示方法都有奇怪的屬性:對數字0兩種不同的編碼方式,出現了+0與-0

  • 反彙編器:一種將可執行程式檔案轉換為ASCII碼形式的出現

  • 這些檔案包含許多16進位制的數字,使用典型的補碼形式來表現這些值

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

  • 強制型別轉換的結果保持位值不變,只改變了解釋方式
  • 對於大多數C語言,處理同等字長的有符號數與無符號數,數值可能會變,但是位模式不會變
    T 2 U w ( x ) = x < 0 = > x + 2 w ; x ≥ 0 = > x ; T2Uw(x) = x < 0 => x + 2^w; x ≥ 0 => x; T2Uw(x)=x<0=>x+2w;x0=>x;
    U 2 T w ( u ) = u ≤ T M a x w = > u ; u > T M a x w = > u − 2 w U2Tw(u) = u ≤ TMaxw => u; u > TMaxw => u - 2^w U2Tw(u)=uTMaxw=>u;u>TMaxw=>u2w
    ( U M a x = 2 w − 1 ; T M a x = 2 ( w − 1 ) − 1 ) (UMax = 2^w - 1; TMax =2^(w - 1) - 1) (UMax=2w1;TMax=2(w1)1)

C語言中的有符號數與無符號數

  • 幾乎所有的機器都使用補碼錶示有符號數

  • 加上字尾U表示無符號常量

  • 當一種型別的表示式被賦給另一種型別的表示式的時候,轉換是隱式發生的

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

  • C語言中 T M i n 32 = − 2147483647 − 1 TMin32 = -2147483647-1 TMin32=21474836471,不寫成-2147483648的理由:補碼錶示是不對稱的

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

  • 常見的一個運算:在不同字長的整數之間做轉換,並不改變其值

  • 擴充套件無符號數:在表示的開頭新增0

  • 擴充套件補碼數:在表示的開頭新增最高位的字元(0 / 1)

截斷數字

  • w->k:丟棄高w-k位。截斷一個數字可能導致溢位
  • 無符號數很容易得到結果
  • 補碼截斷也具有相似的效果,只不過要將最高位轉換為符號位

有關有符號數與無符號數的建議

  • 有符號數->無符號數的強制轉換會導致一些非直觀的行為,這種特性經常導致程式錯誤
  • 避免這一類錯誤的一種方法是絕不使用無符號數

相關文章