Quake III求1/sqrt()

/* 來至 Quake 3 的源碼 */
float CarmSqrt(float x){
    union
    {
        int intPart;
        float floatPart;
    } convertor;
    union
    {
        int intPart;
        float floatPart;
    } convertor2;
    convertor.floatPart = x;
    convertor2.floatPart = x;
    convertor.intPart = 0x1FBCF800 + (convertor.intPart >> 1);
    convertor2.intPart = 0x5f3759df - (convertor2.intPart >> 1);
    return 0.5f*(convertor.floatPart + (x * convertor2.floatPart));
}

也有說法源碼是這樣的

float Q_rsqrt( float number )
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;
    x2 = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;         
    i  = 0x5f3759df - ( i >> 1 ); 
    y  = * ( float * ) &i;
    y  = y * ( threehalfs - ( x2 * y * y ) ); 
    // y  = y * ( threehalfs - ( x2 * y * y ) ); 
    #ifndef Q3_VM
    #ifdef __linux__
      assert( !isnan(y) ); // bk010122 - FPE?
    #endif
    #endif
    return y;
} 


精簡版本的寫法:

//最精簡的1/sqrt()函數:
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 ---此數字比quake3中的數字更優
   x = *(float*)&i;                // convert bits BACK to float
   x = x*(1.5f-xhalf*x*x);    // Newton step, repeating increases accuracy
   return x;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章