2013-07-21 38 views
0

以下C++代碼:浮到int在C + +號轉換

union float2bin{ 

     float f; 
     int i; 
    }; 

    float2bin obj; 
    obj.f=2.243; 
    cout<<obj.i; 

給出一些垃圾值輸出。

union float2bin{ 

     float f; 
     float i; 
    }; 

    float2bin obj; 
    obj.f=2.243; 
    cout<<obj.i; 

給輸出與F相同即價值2.243

編譯器GCC爲int &浮動大小相同即4,但是那有什麼背後的輸出行爲的原因是什麼?

+3

即使尺寸相同,整數和浮點數的表示也是不同的......您期望看到什麼? – Joel

+3

這是UB。你在哪裏讀到轉換可以與工會完成? – Borgleader

+1

@Borgleader你確定嗎?你不是通過不兼容的指針類型來混淆這種混淆嗎? – 2013-07-21 16:55:47

回答

1

的原因是因爲它是不確定的行爲。在實踐中, 在大多數計算機上,您將讀取的int從 作爲float存儲的內容中讀取,但您將閱讀垃圾內容 值,除非您知道該期待什麼。在其他 方向上執行此操作可能會導致程序崩潰的值爲int

在引擎蓋下,當然積分值和浮點數 值有不同的表示,至少在最上面的機器上是 。 (在某些Unisys主機上,您的代碼做012xx您所期望的,但它們不是最常用的系統,而 您可能在桌面上沒有。)基本上,無論類型如何, 你有一個位序列,這將以某種方式被硬件解釋。 C++要求整數使用 整數來表示純粹的二進制表示,這在一定程度上約束了 。它還需要非常大的浮點值範圍 ,或多或少需要一些 形式的指數表示法,其中一些位代表 指數,而其他位代表尾數。使用不同的編碼,每個編碼爲 。

1

原因是因爲浮點值以更復雜的方式存儲,將32位分成符號,指數和分數。如果這些位直接讀取爲整數,它將看起來像一個非常不同的值。

這裏重要的一點是,如果你創建了一個聯合,你就是說它是一個連續的內存塊,可以用兩種不同的方式來解釋。沒有在這個機制中它是否解釋了float和int之間的安全轉換,在這種情況下會發生某種舍入。

更新:你可能想是

float f = 10.25f; 
int i = (int)f; 
// Will give you i = 10 

然而,工會的做法是接近這個:

float f = 10.25f; 
int i = *((int *)&f); 
// Will give you some seemingly arbitrary value 
+0

這是C++,更喜歡'static_cast'和'reinterpret_cast'。 – Griwes

+1

你說得對。然而,在這種情況下,我認爲這可能會傷害這些例子的教學價值,這就是爲什麼我使用C風格演員的原因。 –