两位数平方根速算方法(平方根倒数速算法)

两位数平方根速算方法(平方根倒数速算法)(1)

编程中,在对某一向量进行归一化时,经常需要做上图中的运算, 翻译为代码就是:

y = 1.0 / sqrt(x);

平方根倒数速算法(Fast Inverse Square Root)是一种用于快速计算逆平方根的算法。

两位数平方根速算方法(平方根倒数速算法)(2)

其原理是将先将浮点数当作整数位移,再与神奇数字(0x5f3759df)做减法,这样得到的浮点数结果即是对输入数字的平方根倒数的粗略估计值,最后再进行一次牛顿迭代法,以使之更精确。

该算法最早来源于一款雷神之锤3的游戏,据说比用sqrt()函数的效率要高四倍,但我实际测试下来却发现并非如此,两者的耗时非常接近,可能和不同的硬件、编译器、sqrt()库函数的实现相关,附上测试源码如下:

#include <stdio.h> #include <time.h> #include <math.h> #include <stdint.h> float FastInvSqrt(float number) { const float half = number * 0.5F; union { float f; uint32_t i; } conv = {.f = number}; conv.i = 0x5f3759df - (conv.i >> 1); conv.f *= 1.5F - (half * conv.f * conv.f); return conv.f; } int main() { clock_t clock1, clock2; float x, result, t1, t2; // 1.0 / sqrt() clock1 = clock(); x = 0.0; while (x < 10000.0) { x = 0.001; result = 1.0 / sqrt(x); } clock2 = clock(); t1 = (float)(clock2 - clock1) / (CLOCKS_PER_SEC) * 1000; printf("1.0 / sqrt(x) : %f ms\n", t1); // FastInvSqrt() clock1 = clock(); x = 0.0; while (x < 10000.0) { x = 0.001; result = FastInvSqrt(x); } clock2 = clock(); t2 = (float)(clock2 - clock1) / (CLOCKS_PER_SEC) * 1000; printf("FastInvSqrt(x) : %f ms\n", t2); return 0; }

本地电脑的测试结果如下:

两位数平方根速算方法(平方根倒数速算法)(3)

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页