📜  快速反平方根

📅  最后修改于: 2021-05-25 01:56:22             🧑  作者: Mango

快速平方根逆是一种估算算法{\dfrac{1}{\sqrt{x}}} ,是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中减去结果。这是输入的平方根倒数的第一近似值。再次将这些位视为浮点数,它将运行牛顿逼近方法的一次迭代,从而产生更精确的逼近。

假设有一个指数形式或科学计数形式的数字:
{10^8} =亿
现在,要找到规则的平方根,我们只需将指数除以2:
{\sqrt{{10^8}}}={10^{8/2}}={10^4}=10000
如果想知道平方根的倒数,则将指数除以-2以翻转符号:
{\dfrac{1}{\sqrt{10^8}}}={10^{8/-2}}=10^{-4}=\dfrac{1}{10000}

因此,代码将浮点数转换为整数。然后,将这些位移位1,这意味着将指数位除以2(当我们最终将这些位变回浮点数时)。最后,要取反指数,我们从幻数0x5f3759df中减去。这可以做一些事情:保留尾数(非指数部分,又名5 in:5· 10^8 ),处理奇偶指数,将数位从指数移到尾数,以及各种时髦的东西。

以下代码是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
想要从精选的最佳视频中学习并解决问题,请查看有关从基础到高级C++的C++基础课程以及有关语言和STL的C++ STL课程。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”