快速计算平方根倒数
目标函数
先看代码,重点是Q_rsqrt()函数
#include <iostream>
#include <cmath>
using namespace std;
float Q_rsqrt( float number )
{
long i;//32 bit int
float x2, y;//32 bit float
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}
int main(){
int a[10] = {1,2,3,4,5,6,7,8,9,10};
for (auto i : a){
cout<<Q_rsqrt(i)<<" "<<1/sqrt(i)<<endl;
}
return 0;
}
- 这段代码的关键点在于尽量多用加法、乘法和位运算,而将sqrt运算近似,并且少用除法运算,下面罗列一下值得关注的点
-
这句话是把float类型的y地址取出来,强制转换为指向long类型,也就是32位整数的指针,之后再用i去访问这个long指针。这一步的目的是因为要直接对内存中的y做位运算,而float类型是不支持的。这一步是为了后续运算上的加速。i = *(long *) &y;
- 对于float类型,根据IEEE754标准,分为1+8+23 = 32 位。其中,第一位表示符号,即正或负。8位Exponent表示二进制科学记数法下的指数部分,23位mantissa表示二进制科学记数法下的余数部分。这一部分还需要进一步说明
- 十进制下科学记数法是