2015-11-06 70 views
8

我跑過這段代碼,他們正試圖從float轉換爲int這段代碼做了什麼樣的轉換?

int val[5]; 
union { 
    int i; 
    float f; 
} conv; 

... 
val is updated with some value 
... 
case OUT_FORMAT_FLOAT: 
for (i = 0; i < count; i++) { 
    conv.f = val[i]; 
    val[i] = conv.i; 
} 

但我只是無法理解這是如何工作的。所述val[i]被分配給conv.f然後conv.i用於存儲備份的值成val[i]conv是一個聯合類型,因爲我們使用的是fi將不具有有效的值嗎?

我在這裏錯過了什麼嗎?

+0

請參考http://www.cplusplus.com/doc/tutorial/other_data_types/#unions – hdost

回答

5

它做的東西叫type punning

這裏要記住的是,浮點值通常以與整數不同的格式存儲(最常見的是IEEE floating point format),並且使用union來獲取原始浮點格式。

更具體地講,這是發生了什麼:

  1. 分配conv.f = val[i]。這將val[i]中的整數轉換爲浮點值,並將其存儲在conv.f中。
  2. 分配val[i] = conv.i。這會獲得聯合中存儲的原始浮點位模式,並將其分配給val[i]

這工作,因爲工會是不喜歡用不同的部件的結構。在一個工會所有成員分享相同的內存。修改聯合的一個成員將修改所有成員。


爲什麼工會使用的注意事項:這種轉換可以通過其他方式進行爲好,但那麼這將打破the strict aliasing rule,但使用類型雙關工會是允許的。

+1

我想,你應該還提到,在嚴格的別名規則下,幾乎所有類型的雙關都是未定義的行爲。 Afaik是唯一可以使用'float'位模式的安全方法,就是使用'memcpy()'函數。 – cmaster

+0

這個特別的雙關的實際目的是什麼?我想,檢查整數中的浮點表示位? –

+0

@BlagovestBuyukliev沒有從OP看到更多的上下文,任何人都不可能說。 –

0

union允許不同的數據類型被存儲在相同的位置。空間僅分配給最大數量爲sizeof(member)的會員。

一旦構件f被初始化,i可以從該位置進行訪問。