Doom 3/idTech 4 Fast Inverse Square Rootの実装で使用されているのを見たことがある場所の 1 つです。
このアルゴリズムに慣れていない人にとっては、基本的に浮動小数点数を整数として扱う必要があります。コードの古い Quake (およびそれ以前) のバージョンは、次のようにしてこれを行います。
float y = 2.0f;
// treat the bits of y as an integer
long i = * ( long * ) &y;
// do some stuff with i
// treat the bits of i as a float
y = * ( float * ) &i;
GitHub の元のソース
このコードは、浮動小数点数 のアドレスを取得y
し、それを long (つまり、Quake 時代の 32 ビット整数) へのポインターにキャストし、それを に逆参照しi
ます。次に、信じられないほど奇妙なビットいじりを行い、その逆を行います。
この方法には、2 つの欠点があります。1 つは、入り組んだアドレス オブ キャスト、逆参照プロセスにより、 の値がレジスタ1y
からではなく、メモリから読み取られるように強制されることです。ただし、Quake 時代のコンピューターでは、浮動小数点レジスタと整数レジスタは完全に分離されていたため、この制限に対処するには、メモリにプッシュして戻す必要がありました。
2 つ目は、少なくとも C++ では、この関数のようにブードゥーに相当することを行う場合でも、そのようなキャストを行うことは非常に嫌われていることです。もっと説得力のある議論があると確信していますが、それらが何であるかはわかりません:)
そのため、Doom 3 では、id は新しい実装に次のビットを含めました (これは別のビット調整セットを使用しますが、同様のアイデアを使用します)。
union _flint {
dword i;
float f;
};
...
union _flint seed;
seed.i = /* look up some tables to get this */;
double r = seed.f; // <- access the bits of seed.i as a floating point number
GitHub の元のソース
理論的には、SSE2 マシンでは、これは単一のレジスタを介してアクセスできます。コンパイラがこれを行うかどうかは実際にはわかりません。私の意見では、以前の Quake バージョンのキャスティング ゲームよりも、コードはまだいくらかクリーンです。
1 - 「十分に高度なコンパイラ」引数を無視する