1. 程式人生 > 實用技巧 >《深入理解計算機系統》學習筆記(二)2.2~2.3

《深入理解計算機系統》學習筆記(二)2.2~2.3

《深入理解計算機系統》學習筆記(二)
2.2無符號數的編碼
  假設對於一個w位的無符號整數,用二進位制位元位可以表示為[xw-1 , xw-2 , … , x0]。那麼我們可以用一個函式表示如下:
在這裡插入圖片描述
  每個位Xi都取值為0或1,後一種取值意味著數值2*i應為數字值的一部分。我們看下面的例子。
在這裡插入圖片描述
   那麼很顯然,對於一個無符號編碼的數,由 w 位的二進位制序列構成,那麼它的最小值,即所有位都為 0 ,用位向量表示即:【000…000】。
   UMinw = 0
最大值即所有位都為 1,用位向量表示即:【111…111】
   UMaxw = 1 * (1-2w) / 1 - 2 = 2w - 1
  我們可以得出一個結論:無符號的二進位制,對於任意一個w位的二進位制序列,都存在唯一一個整數介於0 到 2w-1之間,與這個二進位制序列對應。反過來,在0 到 2w-1之間的每一個整數,存在唯一的二進位制序列與其對應。

  在這裡插入圖片描述
上圖中,我們用長度為2*i的指向右箭頭的條表示每個位的位置i。每個位向量對應的數值就等於所有值為1的位對應的條的長度之和。可以發現1,2,3,8可以組成十以內的任意數。
  二進位制 :0101 => 0001+0100 即十進位制: 5=1+4

2.3 補碼編碼
  對於許多應用,我們還希望表示負數值。最常見的有符號數的計算機表示方式就是補碼(two’s-complement)形式。在這個定義中,將字的最高有效位解釋為負權( negativeweight)。我們用函式B2Tw(Binary to Two’s-complement的縮寫,長度為w)來表示:
  對向量:[xw-1 , xw-2 , … , x0]在這裡插入圖片描述


  其中最高有效位 xw-1 也稱為符號位,符號位為 1 時表示負數,當設定為 0 時,表示非負數。我們看下面的例子。
  在這裡插入圖片描述
那麼我們可以得出:當最高位為1,其餘為全部是 0 的時候,即【1000…000】,表示補碼格式的最小值:
    TMinw = -2w-1
 當最高位為 0,其餘為全部是 1 時,即【0111…111】,表示補碼格式的最大值:
    TMaxw = 1 * (1 - 2w-1) / 1 - 2 = 2w-1-1
  通過上面的兩個公式,我們就很好理解為什麼上面C語言資料型別負數的範圍要比正數的範圍大1。
  和上面無符號編碼一樣,我們對於補碼格式編碼也可以得到一個結論:
  對於任意一個w位的二進位制序列,都存在唯一一個介於-2w-1 到 2w-1-1的整數,與這個二進位制序列對應。反過來,對於任意介於-2w-1 到 2w-1-1的整數,存在唯一的長度為w二進位制序列與其對應。
  那麼你就應該明白了為什麼十進位制 -1,在計算機中二進位制表示為 1111 1111,而不是1000 0001,因為計算機是以補碼的形式表示的。
  大家看這張圖是不是特別有意思:在這裡插入圖片描述
  有符號數的其他表示方法:
*反碼和原碼
  反碼定義:除了最高有效位的權是-2w-1-1,而不是-2w-1其餘的和補碼錶示方式一樣
  原碼定義:最高有效位是符號位,用來確定剩下的位是正還是負。 
  我們可以和補碼的定義進行對比: 
  原碼:一個整數,按照絕對值大小轉換為二進位制數,最高位為符號位。
  反碼:將原碼除最高位(符號位)外,其餘各位按位取反,所得到的二進位制碼。正數的反碼為原碼。
  補碼:反碼最低位加1即為補碼。
  對於正整數,原碼、反碼、補碼完全一樣,即符號位固定為0,數值位相同。
  對於負整數,原碼和補碼互相轉換的簡便方法:從數的右邊往左開始數,遇到“0”不理它,直到遇到第一個“1”為止,以後的每一位數取反即是它的原碼或補碼,符號位不變,還是“1”(補碼的補碼是原碼)。
  比如:11010100 ----- 從右往左數,第一位是0,不理它,第二位還是0不理它,第三位是1,那麼從此以後的每位取反,即為它的補碼了.答案為:10101100
  事實上,程式設計師如果希望程式碼具有最大的可移植性,能夠在所有可能的機器上執行,就應該用補碼的形式來表示有符號整數。雖然過去生產過基於反碼錶示的機器,但是幾乎所有的現代機器都是使用補碼。
  注意:浮點數有使用原碼編碼。
  關於整型資料型別的表示和取值範圍,Java標準是非常明確的,它要求採用補碼形式,取值範圍和C語言在64位機器中的情況一樣。在Java中,單位元組資料型別稱為 byte,而不是char,而且沒有long long 資料型別。這些具體的要求都是為了保證無論在什麼機器上,Java程式執行的表現都能完全一樣。