Greg HewgillとIllidanS4は、優れた数学的説明との関連を示しました。ここでは、あまり詳しく説明したくない人のためにまとめます。
いくつかの例外を除いて、数学関数は多項式の合計で表すことができます。
y = f(x)
正確に次のように変換できます:
y = a0 + a1*x + a2*(x^2) + a3*(x^3) + a4*(x^4) + ...
ここで、a0、a1、a2、...は定数です。問題は、平方根などの多くの関数で、正確な値の場合、この合計のメンバー数が無限であり、一部のx ^ nで終了しないことです。しかし、いくつかのx ^ nで停止しても、ある程度の精度までの結果が得られます。
したがって、次の場合:
y = 1/sqrt(x)
この特定のケースでは、おそらく計算速度のため、2番目より上のすべての多項式メンバーを破棄することにしました。
y = a0 + a1*x + [...discarded...]
そして、タスクは、yが正確な値との差が最小になるようにa0とa1を計算するために降りてきました。最も適切な値は次のとおりであると計算されています。
a0 = 0x5f375a86
a1 = -0.5
したがって、これを方程式に入れると、次のようになります。
y = 0x5f375a86 - 0.5*x
これは、コードに表示される行と同じです。
i = 0x5f375a86 - (i >> 1);
編集:実際にここy = 0x5f375a86 - 0.5*x
では、i = 0x5f375a86 - (i >> 1);
floatを整数としてシフトすると、2で除算されるだけでなく、指数も2で除算されて他のアーティファクトが発生するため、同じではありませんが、係数a0、a1、a2 ...を計算することになります。
この時点で、彼らはこの結果の精度が目的には不十分であることを発見しました。そのため、結果の精度を向上させるために、ニュートンの反復の1ステップのみを追加しました。
x = x * (1.5f - xhalf * x * x)
必要な精度が満たされるまで、ループでさらにいくつかの反復を行って、それぞれの結果を改善することができます。これはまさにCPU / FPUでの動作です!しかし、それは1回の反復で十分であるように思われ、これも速度の恩恵でした。CPU / FPUは、結果が格納される浮動小数点数の精度に到達するために必要なだけ反復を行い、すべてのケースで機能するより一般的なアルゴリズムを備えています。
要するに、彼らがしたことは:
CPU / FPUと(ほぼ)同じアルゴリズムを使用し、1 / sqrt(x)の特殊な場合の初期条件の改善を利用し、CPU / FPUが正確に行くまで計算しないで、先に停止します。計算速度の向上。