(int)a、&a、(int)&a、(int&)a的區別

DayThinking發表於2012-12-06

#include <iostream>
 #include <stdio.h>
 #include <string.h>
 #include <conio.h>
 using namespace std;
int main()
 {
 float a = 1.0f;
 cout << sizeof(int) <<endl;//4
 cout << sizeof(float) <<endl;//4
cout << (int)a << endl;//1
 cout << &a << endl; /*取a的地址十六進位制0012FF7C*/
 cout << (int)&a << endl;/*(int)&a:把a的地址強制轉換成十進位制的整型1245052*/
 cout << (int&)a << endl;
 /*(int&)a:將a的引用強制轉換為整型,意思是a所在的記憶體,本來定義的時候為float型別,並初始為1.0f,
 但現在我要按int型別解釋這段記憶體(也就是說a所在的記憶體地址中的資料本來是按float型儲存表示的,你非要按int型來解釋不可)。
 1.0f   在記憶體中的儲存為
 0   011   1111   1   000   0000   0000   0000   0000   0000.
 把他按整型數解釋為2^29+2^28+2^27+2^26+2^25+2^24+2^23=1065353216

(int&)a 相當於
     *(int*)&a

    *(int*)(&a)

    *((int*)&a)

*/    
 
cout << boolalpha << ((int)a == (int&)a ) << endl;//   輸出false.因為1!=1065353216.

float b = 0.0f;
 cout << (int)b << endl;//0
 cout << &b << endl;/*取b的地址十六進位制0012FF78*/
 cout << (int&)b << endl;//0
 cout << boolalpha << ((int)b == (int&)b ) << endl;//   輸出true,因為0==0;

/*
 (int&)a   不經過轉換,   直接得到a在記憶體單元(就是地址)的值  
 (int)a     a在記憶體中的值轉換成int型別  
    
 float型別在記憶體中儲存的形式是   ,符號位   指數   尾數  
 由754標準:階碼採用增碼(該數補碼的反符號),尾數採用原碼  
 所以1.0f   在記憶體中的形式為  
 0011   1111   1000   0000   0000   0000   0000   0000  
 所以輸出的是   0x3f800000  
 0   在記憶體中的的儲存形式  
 0000   0000   0000   0000   0000   0000   0000   0000
 */

return 0;
 }

========================c語言中FLOAT 是如何表示的===========================

c語言中FLOAT 是如何表示的?尾數,階碼是如何在32位上安排的,即哪幾位是
 尾數,哪幾位是階碼,那一位是符號位。聽說與CPU有關,是真的嗎?

    在C++裡,實數(float)是用四個位元組即三十二位二進位制位來儲存的。其中
 有1位符號位,8位指數位和23位有效數字位。實際上有效數字位是24位,因為第
 一位有效數字總是“1”,不必儲存。
     有效數字位是一個二進位制純小數。8位指數位中第一位是符號位,這符號位和
 一般的符號位不同,它用“1”代表正,用”0“代表負。整個實數的符號位用“
 1”代表負,“0”代表正。
     在這儲存實數的四個位元組中,將最高地址位元組的最高位編號為31,最低地址
 位元組的最低位編號為0,則實數各個部分在這32個二進位制位中的分佈是這樣的:3
 1位是實數符號位,30位是指數符號位,29---23是指數位,22---0位是有效數字
 位。注意第一位有效數字是不出現在記憶體中的,它總是“1”。
     
     將一個實數轉化為C++實數儲存格式的步驟為:
     (1)先將這個實數的絕對值化為二進位制格式,注意實數的整數部分和小數部分化為二進位制的方法是不同的。
     (2)將這個二進位制格式實數的小數點左移或右移n位,直到小數點移動到第
 一個有效數字的右邊。
     (3)從小數點右邊第一位開始數出二十三位數字放入第22到第0位。
     (4)如果實數是正的,則在第31位放入“0”,否則放入“1”。
     (5)如果n 是左移得到的,說明指數是正的,第30位放入“1”。如果n是右移得到的或n=0,則第30位放入“0”。
     (6)如果n是左移得到的,則將n減去一然後化為二進位制,並在左邊加“0”補足七位,放入第29到第23位。如果n是右移得到的或n=0,則將n化為二進位制後在左邊加“0”補足七位,再各位求反,再放入第29到第23位。
     
     將一個計算機裡儲存的實數格式轉化為通常的十進位制的格式的方法如下:
     (1)將第22位到第0位的二進位制數寫出來,在最左邊補一位“1”,得到二十四位有效數字。將小數點點在最左邊那個“1”的右邊。
     (2)取出第29到第23位所表示的值n。當30位是“0”時將n各位求反。當30位是“1”時將n增1。
     (3)將小數點左移n位(當30位是“0”時)或右移n位(當30位是“1”時),得到一個二進位制表示的實數。
     (4)將這個二進位制實數化為十進位制,並根據第31位是“0”還是“1”加上正號或負號即可。

    特別地,實數0用C++的float格式表示是00000000000000000000000000000000。
 

如果還不太明白,這裡舉幾個例子。
     一。將23.56化為C++的float格式。
     (1)將23.56化為二進位制後大約是“10111.1000111101011100001”。
     (2)將小數點左移四位,得到“1.01111000111101011100001”。
     (3)這已經有了二十四位有效數字,將最左邊一位“1”去掉,得到“01111000111101011100001”。將它放入第22到第0位。
     (4)因為23.56是正數,因此在第31位放入“0”。
     (5)由於我們把小數點左移,因此在第30位放入“1”。
     (6)因為我們是把小數點左移4位,因此將4減去1得3,化為二進位制,並補足七位得到0000011,放入第29到第23位。
     完畢。
     如果把最左邊定為第31位,最右邊定為第0位,那麼在C++裡,float格式的23.56是這樣表示的:01000001101111000111101011100001。相應地-23.56就是這樣表示的:11000001101111000111101011100001。

    二。將實數0.2356化為C++的float格式。
     (1)將0.2356化為二進位制後大約是0.00111100010100000100100000。
     (2)將小數點右移三位得到1.11100010100000100100000。
     (3)從小數點右邊數出二十三位有效數字,即11100010100000100100000放入第22到第0位。
     (4)由於0.2356是正的,所以在第31位放入“0”。
     (5)由於我們把小數點右移了,所以在第30位放入“0”。
     (6)因為小數點被右移了3位,所以將3化為二進位制,在左邊補“0”補足七位,得到0000011,各位取反,得到1111100,放入第29到第23位。
     完畢。因此0.2356用C++的float格式表示是:00111110011100010100000100100000。其中最左邊一位是第31位,最右邊一位是第0位。

    三。將實數1.0化為C++的float格式。
     (1)將1.0化為二進位制後是1.00000000000000000000000。
     (2)這時不用移動小數點了,這就是我們在轉化方法裡說的n=0的情況。
     (3)將小數點右邊的二十三位有效數字00000000000000000000000放入第22到第0位。
     (4)因為1.0是正的,所以在第31位裡放入“0”。
     (5)因為n=0,所以在第30位裡放入“0”。
     (6)因為n=0,所以將0補足七位得到0000000,各位求反得到1111111,放入第29到第23位。
     完畢。所以實數1.0用C++的float格式表示是:00111111100000000000000000000000。其中最左邊一位是第31位,最右邊一位是第0位。

 摘自:http://hi.baidu.com/jrwen0/item/37004214e30aba8989a9561a

 

 

相關文章