昨天在网上看到一 个求1/sqrt(x)的算法,该算法来自QuakeIII游戏的源码,有测试表明该算法比普通的先求平方根再求倒数的方法快4倍左右,而且相当精确。更 为惊奇的是该算法中一个令人不解的常量0x5f3759df。它的原理是什么,能被改进吗,又是谁设计了这样巧妙的算法?这就是该算法的实现,简单的5行 语句,渗透着巧妙的思维。
float InvSqrt(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating value
i = 0x5f3759df - (i>>1); // gives initial guess y0
x = *(float*)&i; // convert bits back to float
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
return x;
}
如果感兴趣的话可以在网上搜寻关于该算法的详细资料。有人(CHRIS LOMONT)专门为次算法写了十几页的分析,并对该算法进行了改进,所有的改进最后都反映在那个常数上,这就是改进后的结果:
float InvSqrt(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating value
i = 0x5f375a86- (i>>1); // gives initial guess y0
x = *(float*)&i; // convert bits back to float
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
return x;
}
真是越来越感觉到什么也不会了!