強制型別轉換(int)、(int&)和(int*)的區別

lightmare625發表於2018-07-29

我們先來看兩行程式碼:

float x=1.75,y=1.75;

cout<<(int)x<<" "<<(int&)y<<endl;

輸出為:1    1071644672

首先呢,我們來看一下浮點數的格式:

float是單精度32位,所以呢:

  • 符號位 (Sign):0代表正數,1代表為負數;
  • 指數位 (Exponent):用於儲存科學計數法中的指數資料,指數的數值要加上127,如果指數本來是3,那麼要換成130來儲存;
  • 尾數部分 (Mantissa):採用移位儲存尾數部分,因為M的值一定是1<= M <2,所以它絕對可以寫成1.xxxxxxx的形式,所以規定M在儲存時捨去第一個1,只儲存小數點之後的數字,這樣做節省了空間。舉例子:

                    用二進位制的科學計數法表示 1000.1,可以表示為1.0001 * 23

                    用二進位制的科學計數法表示 1110110.1,可以表示為1.1101101 * 26

                    任何一個數的科學計數法表示都為1. xxx * 2n ,尾數部分就可以表示為xxxx,由於第一位都是1嘛,幹嘛還要表示呀?所以將小數點前面的1省略。

舉個例子,浮點數-3.75,先將其轉換成2進位制的,則為-11.11,可以寫成-1.111*2^1,所以符號位是1,加127等於128,指數位是1000 0000,尾數位是111 0000 0000 0000 0000 0000(就是3個1,然後後面20個0,一共23位)。

11000 0000  111 0000 0000 0000 0000 0000

那麼1.75呢?1.75寫成二進位制就是1.11*2^0,所以符號位是0,指數位0+127=127,是0111 1111,尾數位是110 0000 0000 0000 0000 0000(2個1,後面21個0,一共23位),把這幾部分寫在一起就是:

0011 1111 1110 0000 0000 0000 0000 0000

這個浮點數,在記憶體裡儲存的格式就是這樣。如果我們把它當做整數來讀取,那會是多少呢?

輸出為:1071644672

是不是感覺很巧啊,哈哈,發現點什麼了嘛?

(int)x 強制型別轉換,是將浮點數x為引數構造整數(即float轉換為int)

(int &)y 則是告訴編譯器將y看成int對待(記憶體裡的資料不做任何轉換),所以(int &)x值為1071 644 672。

至於(int*)的話,我就不多說啦,就是強制轉換成整型指標,一般人們容易混淆的是(int)和(int&)這兩個。

 

補充:浮點數0.0是比較特殊的,它並不按照上面說的浮點數的格式儲存,浮點數0.0在記憶體裡的儲存是000.....000(全零)。

相關文章