.NETでは、aは32ビットを使用して格納されたIEEEbinary32単精度浮動小数点数float
を使用して表されます。どうやら、コードはビットをにアセンブルしてこの数値を作成し、それをusingにキャストしているようです。キャストとは、C ++の用語で呼ばれるもので、キャストの実行時に変換は行われません。ビットは新しいタイプとして再解釈されるだけです。int
float
unsafe
reinterpret_cast
アセンブル4019999A
された数は16進数または01000000 00011001 10011001 10011010
2進数です。
- 符号ビットは0です(正の数です)。
- 指数ビットは
10000000
(または128)であり、指数128-127 = 1になります(小数部に2 ^ 1 = 2が掛けられます)。
- 小数ビットは
00110011001100110011010
、他に何もないとしても、ほとんど認識可能な0と1のパターンを持っています。
返されるfloatは、2.4が浮動小数点に変換されたものとまったく同じビットを持ち、関数全体をリテラルに置き換えることができます2.4f
。
分数の「ビットパターンを壊す」ような最後のゼロは、おそらく浮動小数点リテラルを使用して記述できるものと浮動小数点を一致させるためにありますか?
では、通常のキャストとこの奇妙な「安全でないキャスト」の違いは何ですか?
次のコードを想定します。
int result = 0x4019999A // 1075419546
float normalCast = (float) result;
float unsafeCast = *(float*) &result; // Only possible in an unsafe context
最初のキャストは整数1075419546
を受け取り、それを浮動小数点表現に変換し1075419546f
ます。これには、元の整数を浮動小数点数として表すために必要な符号、指数、および小数ビットの計算が含まれます。これは、実行する必要のある重要な計算です。
2番目のキャストはより不吉です(そして安全でない状況でのみ実行できます)。は、整数が格納されている場所へのポインタを返す&result
アドレスを取ります。次に、ポインターの間接参照演算子を使用して、ポインターが指す値を取得できます。を使用すると、その場所に格納されている整数が取得されますが、最初にポインタを(へのポインタ)にキャストすると、代わりにfloatがメモリ位置から取得され、floatがに割り当てられます。したがって、の説明は、へのポインタを与え、そのポインタがaへのポインタであると想定し、ポインタが指す値を取得します。result
1075419546
*
*&result
float*
float
2.4f
unsafeCast
*(float*) &result
result
float
最初のキャストとは対照的に、2番目のキャストは計算を必要としません。に格納されている32ビットをresult
押し込むだけですunsafeCast
(幸いにも32ビットです)。
一般に、そのようなキャストの実行は多くの点で失敗する可能性がありますが、使用することによりunsafe
、コンパイラーに自分が何をしているかを知っていることを伝えています。