2016-03-23 13 views
1

私は、揺れに使用される逆sqrtのサンプルコードを探しています。typecastingの場合、これは*(int *)&xを意味しますか?

私はfloat型の変数を参照してください。float x = 16;

をし、その後int変数は、この式の値を取ります。私は(右から左に)それを理解int i = *(int*)&a;

方法は、それがかかることです変数aのアドレスを整数型ポインタに型キャストし、そのポインタの値をとり、iに代入します。

コンソールに変数iを出力すると、大きな整数値になります。 誰かがここで何が起こっているの詳細を説明することができますか?

私は変数i16であると予想していたためです。

+1

このコードは、厳密なエイリアシングルール違反による未定義の動作を示しています。これは、おそらくそれについて知る必要がある唯一のものです。 – SergeyA

答えて

9

&aは、aのfloatのアドレスをとります。 (int *)は同じアドレスを保持しますが、ここにintが格納されているとふりをするようにコンパイラに指示します。 int i = *は、そのアドレスからintをロードします。

したがって、浮動小数点数と同じビットパターンの整数が得られます。浮動小数点数と整数は非常に異なるエンコーディングを持つため、非常に異なる値になります。

floatはlike thisとなる可能性がありますが、必須ではありません。あなたのアーキテクチャは何か他のことをするかもしれません。可能であれば、著者はfrexpのプラットフォーム固有の最適化バージョンを実行しています。

int i = (int)x;は、floatをintに変換するだけで、16となります。

+1

私はそれがおそらく仮数や指数を引き出す最適化された試みだと示唆して編集しました。 floatからintへの変換は高価です(ただし、相対的な意味で)。しかし、値が常に0から1の範囲にあることを知っていると仮定した場合、つまり指数を既に知っている場合、仮数をそのままビットとしてあなたのint。典型的な例は、CPU上での画像操作です。すべての色が[0.0,1.0]で数字で始まる場合、通常は出力も[0.0、1.0]ですが、グラフィックスカードに整数バイトを送信する必要があります。 – Tommy

+1

あなたが言及しなかったことの1つは、厳密なエイリアシング規則違反のためにコードが未定義の動作であることです。 – SergeyA

+0

@SergeyA確かに、私は適切な編集を行うための完全な資格は感じません。 C99以降、6.2.7ではint型とfloat型を含まないよう互換型を定義しており、6.5.16ではポインタの代入に互換性のあるポインティング型の必要性が強制されています。途中に一時的な割り当てがない場合、同じルールが適用されることを示すための最終的なリンクを見つけるのが難しいです。だからコミュニティウィキとマークしました。最初に – Tommy

関連する問題