2016-09-13 15 views
-1

私はこの関数が何をしているのか、それがなぜ有用であるのか不思議です。私はこれが浮動小数点型の整数型への型変換を行うことを知っています。詳細な説明は感謝します。アドレス浮動小数点型からint型への型変換

unsigned int func(float t) 
{ 
    return *(unsigned int *)&t; 
} 

おかげ

+1

これはです追加の講義として、http://www.wikipedia.org/wiki/Type_punningを参照してください。cocoawithlove.com/2008/04/using-pointers-to-recast-in-c-is-bad.html – Amadeus

答えて

3

それは、そのバイナリ表現所与floatのバイナリ表現と同じであるunsigned integerを返します。

uint_var = func(float_var); 

が本質的に等価である:

memcpy(&uint_var, &float_var, sizeof(uint_var)); 

このような種類のパンニングも未定義の動作になるので、このようなコードは、携帯型ではありません。ただし、コンパイラのインプリメンテーション依存動作が分かっている低レベルプログラミングでは珍しくありません。

float
+0

これは未定義の動作です。 – EOF

+0

@EOF - 技術的にはそうですが、システムプログラミングと組み込みプログラミングでは一般的な方法ですが、この手法には妥当な選択肢がありません。 – phonetagger

+0

@ EOF私はそれについて何かを加えました。 – Barmar

3

を仮定するとunsigned intは同じサイズであり、それは供給floatとして(ビットの根底にある)同じバイナリ表現を用いて表されるunsigned int値を与えます。

呼び出し元は、返された値にビット単位の演算を適用し、個々のビット(符号ビット、指数部と仮数を構成するビットなど)に個別にアクセスできます。

(unsigned int *)は、&tunsigned intへのポインタに変換します。 *は、その位置の値を取得します。その最後のステップは正式に未定義の振る舞いをしています。

floatunsigned intが異なるサイズの実装(コンパイラ)の場合、動作は何でもかまいません。

+1

'float'と' unsigned'のサイズに関係なく、動作は未定義です。 – EOF

+0

それは本当です、EOFです。したがって、 "その最後のステップ..."文。 – Peter

2

これは、floatをint自体に正確に変換するものではありません。指数の

  1. ・サイン+ 7ビット
  2. 8thBitOfExponent + first7bitsOfMantissa
  3. 最終
  4. 仮数部の次の8:ほとんどの(実質的にすべての)プラットフォームでは、フロートは、以下の4つのバイトの32ビットのエンティティであります8の仮数

一方、符号なしの値は32ビット(プラットフォームによって決まるエンディアン)です。

ストレートフロート→符号なし整数変換では、浮動小数点の実際の値を、最も近い符号なしの内部に収めるようにしようとします。このコードは、浮動小数点数を意味するものを解釈しようとせずに浮動小数点を構成するビットをそのままコピーします。したがって、1.0fは0x3f800000に変換されます(ビッグエンディアンを前提とします)。

上記のように、プラットフォームに関するかなりの数の仮定があります(プラットフォームによっては、サイズが不一致になり、切り詰めやメモリの破損に至る可能性があります)。とにかく、何が起こっているのかをもっと明白にするために、明示的にmemcpy()を行うことを好みます。

関連する問題