快速平方根逆是一种估算算法 ,是IEEE 754浮点格式的32位浮点数x的平方根的倒数(或乘逆)。在许多应用中,例如视频游戏中的矢量归一化,计算倒数平方根是必需的,并且主要用于3D编程所涉及的计算中。在3D图形中,使用表面法线,长度为1的3坐标矢量来表示照明和反射。表面法线很多。计算它们涉及归一化许多向量。规范化通常只是一个很好的除法术语。勾股定理计算点之间的距离,除以距离有助于归一化向量:
该算法以其在1999年Quake III Arena Game的源代码中的实现而闻名,该游戏是大量使用3D图形的第一人称射击游戏。那时,计算浮点数的倒数通常在计算上非常昂贵,尤其是在大规模情况下;快速逆平方根绕过了这一步。
算法 :
步骤1:它将浮点输入的位重新解释为整数。
i = * ( long * ) &y;
第2步:获取结果值并对其进行整数运算,从而得出我们要寻找的值的近似值。
i = 0x5f3759df - ( i >> 1 );
步骤3:结果不是近似值本身,而是一个整数,如果您将位重新解释为浮点数,则近似值就是近似值。因此,代码执行了与步骤1中的转换相反的操作,以返回到浮点数:
y = * ( float * ) &i;
步骤4:最后,它运行Newton方法的单次迭代以提高近似度。
y = y * ( threehalfs - ( x2 * y * y ) ); //threehalfs = 1.5F;
该算法接受32位浮点数作为输入,并存储减半的值以供以后使用。然后,将表示浮点数的位视为32位整数,执行逻辑右移一位,然后从幻数0x5F3759DF中减去结果。这是输入的平方根倒数的第一近似值。再次将这些位视为浮点数,它将运行牛顿逼近方法的一次迭代,从而产生更精确的逼近。
假设有一个指数形式或科学计数形式的数字:
=亿
现在,要找到规则的平方根,我们只需将指数除以2:
如果想知道平方根的倒数,则将指数除以-2以翻转符号:
因此,代码将浮点数转换为整数。然后,将这些位移位1,这意味着将指数位除以2(当我们最终将这些位变回浮点数时)。最后,要取反指数,我们从幻数0x5f3759df中减去。这可以做一些事情:保留尾数(非指数部分,又名5 in:5· ),处理奇偶指数,将数位从指数移到尾数,以及各种时髦的东西。
以下代码是Quake III Arena的快速反平方根实现(在Quake III Arena Game中编写的确切原始注释)。
// CPP program for fast inverse square root.
#include
using namespace std;
// function to find the inverse square root
float inverse_rsqrt( float number )
{
const float threehalfs = 1.5F;
float x2 = number * 0.5F;
float y = number;
// evil floating point bit level hacking
long i = * ( long * ) &y;
// value is pre-assumed
i = 0x5f3759df - ( i >> 1 );
y = * ( float * ) &i;
// 1st iteration
y = y * ( threehalfs - ( x2 * y * y ) );
// 2nd iteration, this can be removed
// y = y * ( threehalfs - ( x2 * y * y ) );
return y;
}
// driver code
int main(){
int n = 256;
float f = inverse_rsqrt(n);
cout << f << endl;
return 0;
}
输出 :
0.0623942