1

これが私がやろうとしていることです:

//Let Bin2Float be a magic macro that packages specified bit pattern into float as a constant

const float MyInf = Bin2Float(01111111,10000000,00000000,00000000);

ビットパターンを整数にパッケージ化する方法(「バイナリ定数」ハック)は誰もが知っています。この魔法のプロトタイプマクロへの入力は、対応する32ビット整数のバイナリ定数マクロの場合と同じです。ビットを整数定数にパッケージ化することは問題ではありません。しかし、ポインターと共用体のしゃれで遊んだ後、整数をfloatに型のパンニングすると、多くの問題が発生することに気付きました(MSVC側、gcc側)。したがって、要件のリストは次のとおりです。

  1. gcc(Cモード)、g ++、MSVCでコンパイルする必要があります(2つの別々のバージョンを実行するために条件付きコンパイルを使用する必要がある場合でも)
  2. CとC++の両方でコンパイルする必要があります
  3. 結果のアセンブリコードでは、動的に計算されるのではなく、ハードコードされた定数にコンパイルする必要があります
  4. memcpyを使用してはいけません
  5. 静的変数またはグローバル変数を使用してはなりません
  6. 厳密なエイリアシングの問題を回避するために、ポインタベースの型のパンニングを使用しないでください
4

1 に答える 1

4

まず、このように浮動小数点定数を指定する必要はほとんどありません。無限大の場合は、を使用しますINFINITY。NaNの場合は、NANまたはを使用しますnanf(string)。これらはで定義されてい<math.h>ます。コンパイラーはコンパイルし、ある種のアセンブリ言語定数に変換する可能性がINFINITYありNANます(読み取り専用データ・セクションにある可能性があり、命令の即時フィールドなどで形成される可能性があります)。ただし、C標準では保証されていないため、コンパイラの実装者以外はこれを保証できません。nanf文字列が定数の場合、コンパイラは定数に最適化できますが、関数呼び出しが発生する可能性があります。有限数の場合は、16進浮動小数点定数(「0x3.4p5」など)を使用します。この方法で完全に指定できないIEEE754浮動小数点オブジェクトは、最後のビットまではNaNだけです。および関数はC標準nannanf完全に指定されていないため、実装で提供されていない限り、仮数ビットを完全に制御することはできません。

私はあなたがほのめかしているバイナリ定数ハックに慣れていません。Bin2Unsignedを提供するマクロがあるとするとunsigned int、次のように使用できます。

const float MyInf = (union { unsigned u; float f; }) { Bin2Unsigned(…) } .f;

つまり、信じられないかもしれませんが、ビットがfloatとして再解釈されるまでの標準のC構文とセマンティクスです。明らかに、ビットの解釈は実装に依存します。ただし、複合リテラルとユニオンによる再解釈は、C標準で指定されています。

私はgccバージョン4.2.1(Apple Inc.ビルド5666)でテストし、x86_64をターゲットにして、それ以外の場合は-O3とデフォルトのオプションを使用し、結果のアセンブリコードは定数を使用しました.long 2139095040

于 2012-12-25T19:39:01.177 に答える