2015-11-06 11 views
8

私は、彼らがこのコードはどのような変換をしていますか?

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; 
} 

をintにfloat型から変換しようとしているこのコードは、全体で走ったんだけど、これがどのように動作するかを理解することはできませんよ。 val[i]conv.fに割り当てられ、その後conv.ival[i]にストアバック値に使用されます。 convは、fを使用しているため、ユニオンタイプです。iは有効な値ではありません。

は、私はここで何かが足りないのですか?

+0

は、私が思うhttp://www.cplusplus.com/doc/tutorial/other_data_types/#unions – hdost

答えて

5

それはtype punningと呼ばれる何かをやっています。

ここで覚えておくべきことは、浮動小数点値は整数(通常はIEEE floating point format)とは非常に異なる形式で格納されることが多く、ユニオンの使用は生浮動小数点形式を取得することです。

具体的には、これは何が起こるかです:

  1. 割り当てconv.f = val[i]val[i]の整数が浮動小数点値に変換され、conv.fに格納されます。
  2. 割当val[i] = conv.i。これにより、ユニオンに格納されている生の浮動小数点ビットパターンが取得され、val[i]に割り当てられます。

組合は、別のメンバを持つ構造体のようではありませんので、これは動作します。組合では全員シェアーは同じメモリです。ユニオンの1つのメンバーを変更すると、すべてのメンバーが変更されます。


組合が使用されている理由についての注意

:しかしタイプpunningための組合が許可されている使用して、この変換は、他の方法で作ることができるが、その後それは the strict aliasing ruleを破ります。

+1

を参照してください、あなたはまた、ほぼすべてのタイプpunningは厳しいエイリアシング規則の下で未定義の動作であることを言及する必要があります。 Afaikは、 'float'のビットパターンを得る唯一の安全な方法は、' memcpy() '関数を使うことです。 – cmaster

+0

この特定の懲罰の実際的な目的は何でしょうか?私は整数の浮動小数点表現ビットを検査すると思いますか? –

+0

@BlagovestBuyukliev OPからより多くの文脈を見ることなく、誰もが言うことは不可能です。 –

0

unionは異なるデータ型が同じ場所に保存することを可能にします。スペースは、最大値がsizeof(member)のメンバーのみに割り当てられます。

部材fが初期化されると、iはその場所からアクセスすることができます。

関連する問題