Writing Tmin in C (翻譯)

CS:APP Web Aside DATA: TMIN :Writing TMin in C

寫這篇博客是在看到CSAPP第二章,Tmin寫法這一部分。爲了給自己加深理解,就將官網上的旁註http://csapp.cs.cmu.edu/public/waside/waside-tmin.pdf翻譯了一下。中間有些部分跳過,是因爲我覺得於Tmin關係不大,或者是寫的太繁複。


謝絕轉載

 

1.     案例

在表2-18和練習題2.21中,我們仔細的將Tmin的值寫成-2147483647-1。那麼爲什麼我們不將它寫成-2147483648或者0x80000000?當我們查看頭文件limits.h,發現它和我們使用類似的定義方法來定義Tmin和TMax:

/* Minimum and maximum values a ‘signed int ‘canhold.*/

#define INT_MAX 2147483647

#define INT_MIN (-INT_MAX – 1)

 

不幸的是,補碼錶示的不對稱性和C語言轉換規則之間這種奇怪的交互,迫使我們使用奇怪的方式來寫Tmin。雖然理解這個問題需要我們專研C語言標準中一些隱晦的角落,但是它也能幫助我們理解整數數據類型和表示的一些細微之處。

 

假設我們將Tmin寫成-2147483648,在32位機器中實現,使用表2-8的數據大小。當編譯器遇到-X形式的數字時,首先決定X的數據類型和數據值,然後取反。2147483648對於int而言,超出了表示範圍。編譯器會嘗試尋找一個可以準確表示該數值的數據類型。


Figure 1 :表示整形常量的數據類型。依賴C語言版本以及進制(十進制或十六進制),按照順序第一個可以準確表示數值的數據類型就是所求的。


Figure 2:TMIN的不同數據類型。依賴C語言版本和進制(十進制或十六進制),我們爲兩種表達式找到了三種不同的數據類型,包括值是正數的案例。

  依照不同的語言版本,它從表一中按照順序尋找合適的數據類型。對於ISO C90,它從int到long,再到unsigned,直到找到能表示2147483648的數據類型。正如我們在2.3.3看到的那樣,在32位機器中,2147483648和-2147483648有相同的位表示,所以最後的數據類型就是unsigned,值是2147483648。而對於ISO C99,最後找到的數據類型是long long,值是-2147483648。

  而對於十六進制常量0x80000000,在32 機器上,最後的數據類型都是unsigned,值是0x80000000(等價於2147483648)。

對於64位及其,無論是ISO C90還是ISO C99,十進制形式的數據類型都是long,值是-2147483648,十六進制都是unsigned,值是0x80000000(等價於2147483648)。

所有的不同都已經在表二中總結,對於結果是longlong long 數據類型的,常量都是負值,並且是64位表示。而對於結果是unsigned的數據類型,常量是正數,並且是32位表示。

這些結果可在下面的代碼中明顯的看出不同:

Int dcomp = (-2147483648  <  0);

Int hcomp = (0x80000000  <  0);

 

這兩行都嘗試去表示Tmin,作爲十進制或十六進制,並且測試該值是否小於0.依賴於編譯器和字的大小,我們可以發現dcomp的值可以是0,也可以是1,這表明十進制常量可能是正數,也可能是負數。但是hcomp的值始終是0,表示十六進制的常量始終是正數。我們看上去很簡單的寫出Tmin32的任務,比預想的要複雜的多。

 

練習題1:

考慮下面的代碼:

Int dtmin = -2147483648;

Int dcomp2 = (dtmin < 0);

Int htmin = 0x80000000;

Int hcomp = (htmin < 0);

 

我們在32位和64位機器上,使用兩種不同的補碼來表示整形,並且使用ISO-C90和ISO-C99兩種方式來編譯。在所有的情況中,我們發現dcomp和hcomp2始終都是1,進一步的測試表明,dtmin和htmin事實上等於Tmin(大小)。解釋爲什麼這段代碼對不同編譯器和語言版本的結果都相同。

 

因爲最後都會被轉化成int型,那麼數值大小就是-2147483648,而不會有歧義。

2 應用

對許多程序而言,由字大小和語言標準引起的模糊不會影響程序的行爲(例如問題1)。然而,現在我們可以理解爲什麼通常的將Tmin 寫成-2147483647-1會有一個更合適的結果。因爲2147483647就是Tmax的值,因此不需要考慮使用表一的轉化規則。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章