3

reinterpret_cast を使用して整数を float に変換すると、メモリの内容が変化します。

例えば、

   float fDest = 0;
  __int32 nTempDest = -4808638;

  fDest = *reinterpret_cast<float*>(&nTempDest);

変数値 nTempest の 16 進表現は '42 a0 b6 ff' ですが、reinterpret_cast 後の fDest の内容は '42 a0 f6 ff' です。

この 3 番目のバイトが b6 から f6 に変更された理由を誰でも答えられるでしょうか。

4

2 に答える 2

2

純粋な C++ では、これは実際には未定義の動作です。それにもかかわらず、あなたが見るものには説明があります。

あなたが与える16進表現は、メモリのバイト単位のビューからのものだと思います。明らかに、リトルエンディアン アーキテクチャを使用しています。したがって、開始する 32 ビットの量は 0xffb6a042 であり、これは実際には -4808638 の 2 の補数表現です。

IEC 60559 単精度浮動小数点数 (これも 32 ビット) として、0xffb6a042 は負であり、NaN を通知します。この表現の NaN の形式は (バイナリで)

s1111111 1qxxxxxx xxxxxxxx xxxxxxxx

ここで、s は符号、x は任意で、静止 NaN の場合は q=1、シグナリング NaN の場合は q=0 です。

ここで、シグナリング Nan を fDest に割り当てるという点で使用しています。これにより、浮動小数点シグナリングがアクティブな場合、浮動小数点無効例外が発生します。デフォルトでは、このような例外は単純に無視され、シグナリング NaN 値は伝搬時に「静止」されます。

そのため、fDest への割り当てでは、NaN が伝播され、実装はビット 22 を設定することによってそれを quiet NaN に変換します。これは、観察した変更です。

于 2013-01-25T20:20:04.173 に答える
1

あなたのコードはUndefined Behavior(UB)を生成します。
reinterpret_castあるポインター型から別のポインター型にキャストし、それを元のポインター型にキャストして戻すと、元のデータが得られるという保証のみが与えられます。それ以外はUBを生成します[注1]

次の事実に依存できないため、これは UB です。

sizeof(float) == sizeof(nTempDest)

これはすべての実装で保証されているわけではなくtrue、厳密なエイリアシングに従うものには当てはまりません。実装が得られない場合は、未定義の動作です。


[注 1]このルールには例外があります。これらのコーナー ルールに頼る必要がある場合は、荒れた海で泳いでいることになります。

于 2013-01-25T06:30:48.467 に答える