深入理解計算機系統 第二章 信息的表示和處理

[toc]

概 述

本章主要講了整型和浮點型的各種用法。但我更想強調的是使用數據時可能會出現的誤區

很多符合人常識的數學計算,在計算機中卻可能得到不可思議的結果。
比如兩個整數相加或者相乘,可能得到一個負數值,兩個負數值相加,可能得到一個正值

所以我會在下一個靈魂拷問部分,把公開課上教授舉出的各種puzzle都總結一下,如果你每個題都做對了,那么就說明掌握的非常好,不需要細看這篇博客了。

這本書主要基于 x86-64位,所以指針大小為8個字節,int類型為4個字節,float也是4個字節
這篇不是傻瓜型總結,要看的話需要一定的C語言基礎。

配套課程實驗 DataLab請看我的博客:深入理解計算機系統 CSAPP DataLab 2019.

參考資料:B站深入理解計算機系統公開課(有中文字幕,強烈推薦)


整型


整型 靈魂拷問

// initialization
int x = foo();
int y = bar();
unsigned ux = x;
unsigned uy = y;

x, y為int整型,ux,uy為無符號整型。x,y的值可能是,int類型取值范圍內的任何一個數。
請問下列問題是否對所有符號要求的 x,y 都成立

  1. 已知 x < 0,可以得到 (x * 2) < 0

  2. 所有 ux 滿足 ux >= 0

  3. 已知 `x & 7 == 7 ,可以得到(x << 30) < 0``

  4. 所有 ux 滿足 ux >= -1

  5. 已知 x > y,可以得到 -x < -y

  6. 所有 x 滿足 x * x >= 0

  7. 已知 x > 0 && y > 0,可以得到 x + y > 0

  8. 已知 x >= 0,可以得到 -x <= 0

  9. 已知 x <= 0,可以得到 -x >= 0

  10. 所有x 滿足 (x | -x) >> 31 == -1


整型 靈魂拷問答案

  1. False, 反例:Tmin,也就是INT_MIN
  2. True, 無符號數一定大于0
  3. True, 向左偏移后,符號位為1,所以一定小于0
  4. False,有符號和無符號數在運算得時候,會自動講有符號轉換成無符號數。-1是最大的無符號數
  5. False, 反例:假設 x == 0, y == Tmin,x,y的相反數是x,y本身,所以后者不成立
  6. False
  7. False, Tmax + 1 == Tmin
  8. True
  9. False, 只有一個反例,那就是 x == Tmin
  10. False, 唯一反例,x == 0

整型學習要點

  • 64位和32位區別是什么?

64和32位,可以理解為指針的大小不同。32位系統,指針是4個字節,64位系統,指針是8個字節。
學過C都知道,指針上面保存的是地址,那么32位系統,指針的地址只有32位地方放,我們可以算一下最多存多少東西:

32位存放地址,有2 ^ 32種可能性,之后除以3個1024得到多少個G。最后得到4個G。也就是說32位系統的內存最多就是4G,多了就是浪費。64位就不一樣了,當然我們現在的電腦,根本沒法把2^64的內存填滿。

  • 溢出

整型溢出的所有處理方法都是截斷,而且C編譯器不會給出任何的溢出警告。無論是乘法還是加法,只要超出了int的32位,都會只保留最低的32位,保留下來的符號位是1變成了負數,是0就變成非負數。

  • 補碼

請點鏈接,我自己的寫的另一篇博客:為什么計算機使用補碼

  • Tmin Tmax

Tmin 是int的最小的數: 0x80000000
Tmax 是int的最大的數: 0x7FFFFFFF

對一個整數取相反數: ~x + 1,我也不知道為啥,就當數學定理背過就行了
所有整數有兩個數的相反數是其本身: 0 和 Tmin,因為正數范圍內沒有一個數是和Tmin對應的。

他們之間還有一個關系 Tmax + 1 == Tmin

  • 移位

左移位比較簡單,就移動就行了,右邊多出來的用 0 填補

右移位看情況,不同的機器操作不一樣。但是絕大多數情況下,右移位是算術移位,那就是左邊多出來的位使用符號位填補

int是32位,如果你移動50位會怎么樣?正常情況下系統會移動 (x mod 32) 位。也就是 50 % 32 == 18


浮點型

很多人(比如我)對浮點型的了解很有限,所以這里就講具體做法吧,就不上題了


浮點型學習要點

前思后想不如直接提供一個講的好的鏈接:IEEE浮點數
浮點數這個東西,其實在實際項目里面很難遇到,可能數據分析啥的用的比較多,但是正常的項目其實整型完全可以做,所以我這里就講一下要點。

  • 組成

浮點數是由3部分組成的,符號位,指數位,尾數位
用float舉例,符號位占1位,指數占8位,尾數占23位。
這8位指數,你要在中間割一刀,這一刀就是小數點,小數點左側的數就像整型二進制一樣,從小到大代表 1,2,4,8。但是小數點右邊的數正好相反,代表,1/2,1/4,1/8,1/16。

  • 特性
  1. 如果你畫一個數軸,然后把float能代表的點都畫在上面,你會很明顯的發現,越靠近0,點越密集,越遠離0,點越稀疏
    這是因為尾數是一個固定的數,float從0到正無窮的過程中,指數會慢慢變大,一開始指數很小,所以點和點之間貼的特別近。但是之后指數爆炸增長,所以點和點離得特別遠。

  2. 在上部分組成里面說的,指數部分是有小數點的,那么就容易理解,如果你這個數很大,那么精確性會變差,因為好多指數位都給了小數點左側用,右側少了自然不精確,反之亦然。

  • 結合律

浮點數不滿足結合律。具體請看反例

(3.14 + 1e10) - 1e10 == 0

3.14 + (1e10 - 1e10) == 3.14

(1e20 * 1e20) * 1e-20 != 1e20
(1e20 * 1e20) * 1e-20 == infinite
1e20 * (1e20 * 1e-20) == 1e20


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。