在实现"Carmack's Inverse Square Root"算法时,我注意到结果似乎存在偏差。下面的代码似乎可以得到更好的结果:
关键区别在于倒数第二行的“更多魔法”。由于初始结果过低,这个因素是相当恒定的,所以只需一条指令,就可以将19 * 2^(exponent(y)-bias)加到结果中。这似乎给我额外增加了3位,但我是否忽略了什么?
float InvSqrtF(float x)
{
// Initial approximation by Greg Walsh.
int i = * ( int* ) &x;
i = 0x5f3759df - ( i >> 1 );
float y = * ( float * ) &i;
// Two iterations of Newton-Raphson's method to refine the initial estimate.
x *= 0.5f;
float f = 1.5F;
y = y * ( f - ( x * y * y ) );
y = y * ( f - ( x * y * y ) );
* ( int * )(&y) += 0x13; // More magic.
return y;
}
关键区别在于倒数第二行的“更多魔法”。由于初始结果过低,这个因素是相当恒定的,所以只需一条指令,就可以将19 * 2^(exponent(y)-bias)加到结果中。这似乎给我额外增加了3位,但我是否忽略了什么?