所读的原文地址之一是在 http://www.matrix67.com/blog/archives/362
另一个,阿弥陀佛,忘记了。。。
先不多说,先上代码,
计算开平方根的倒数,
float Q_rsqrt( float number ) { long i; float x2, y; 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 #ifndef Q3_VM #ifdef __linux__ assert( !isnan(y) ); // bk010122 - FPE? #endif #endif return y; }
上述代码计算的就是1/√number, 如果再乘以number其实就是计算了√number了。
这里面使用牛顿迭代,逻辑是很简单的:
f(x) = a - 1/ x2 欲计算1/sqrt_root(a), 亦即√a,f(x) = 0;
f'(x) = -2/x3
按照迭代公式, x' = x - f(x)/f'(x); 在上述代码中迭代两次,所得到的结果y就是1/√a ;
但是一开始猜测是数值 i 或者 y,利用了神奇的常数 0x5f3759df, 在这里有一论文论述了选择的问题,不过我还没有看。
今天2013.11.13, 在这里:http://blogread.cn/it/article/3299?f=wb 又看到了相关的介绍,贴在此处,留作备忘。
待看完后在来补充心得。。。:
::(未完待续)