【学习笔记】快速平方根倒数算法
来源:互联网 发布:vs for mac 离线安装 编辑:程序博客网 时间:2024/05/16 18:48
很以前久,看《DOOM启示录》的时候就看到,当年卡马克大神在《雷神之锤》中使用了一个神奇的数字,能够通过位操作快速计算平方根倒数
代码实现
首先是这个神奇算法的代码:
float fast_inverse_sqrt(float x){ float half_x = 0.5 * x; int i = *((int *)&x); // 以整数方式读取X i = 0x5f3759df - (i>>1); // 神奇的步骤 x = *((float *)&i); // 再以浮点方式读取i x = x*(1.5 - (half_x * x * x)); // 牛顿迭代一遍提高精度 return x;}
其中最最重要的就是第二步,通过这个神奇的步骤,能够得到x平方根倒数的近似值。前后穿插着用整型读取浮点数等等,实在是不知所云。但实际上,其中包含着很有意思的数学背景(每次一提到数学,我就觉得好方)。
背后的数学
首先来重新温习一下机组里面的浮点数基础知识(机组60分默默飘过)。
单精度浮点数
单精度浮点数有32bit,包括1位符号位s,8位指数位e,23位尾数位m(赞一下CSDN的markdown编辑器的latex数学公式的功能~):
其表示的数值为:
再规定M表示以整数方式解释尾数二进制位的值,E表示相同的方式解释指数部分的值。可以得到以下的转换关系:
那么对于一个浮点数的二进制位
平方根倒数近似计算
下面开始进入正题:
对于输入x,我们要计算的是
观察发现,上式等号两边均有
因此我们近似的用
移项合并后得到:
恰好我们又发现,在等式的两边都含有以整数方式解释浮点数的表示
由此,我们得到了一个比较有用的近似公式,
牛顿迭代提高精度
经过上一步,我们有了初步的近似结果,为了进一步提高精度,我们再用牛顿迭代法计算一次。牛顿迭代法描述的是,给定连续函数f(x),对于方程f(x)=0,确定任意初始的
我们要计算的式子为
也就是最后一步的代码了。
更多讨论
上述推导过程中可以看出,不同次方根在我们的计算中仅仅是作为一个因子而存在的,因此将该近似算法完全可以推广到其他次方根的情况下。另外,对于64位浮点数,我们也可以采用完全相同的推导过程来得到相似的结果。这只是一个近似算法,它与真实计算值之间的偏差与神奇数字的取值有很微妙的关系,这篇博客对这个问题进行了一些讨论。
真是神奇的算法!
- 【学习笔记】快速平方根倒数算法
- 快速平方根(平方根倒数)算法
- [算法笔记]——快速倒数平方根算法
- 快速求平方根倒数算法
- 算法学习笔记(二):平方根倒数速算法
- 【转】卡马克快速平方根——平方根倒数算法
- 卡马克快速平方根(平方根倒数)算法(转)
- 《雷神之锤III》求平方根倒数(快速平方根(倒数)算法)之C#版
- [转]快速计算平方根倒数的一个算法
- [转贴]《雷神之锤III》里求平方根倒数的函数(快速平方根(倒数)算法)
- 求平方根倒数的算法
- 求平方根倒数的算法
- 【编程】超快速计算平方根的倒数
- 软件快速计算平方根与平方根的倒数
- 快速平方根算法
- [转]快速平方根算法
- 快速平方根算法
- 快速求平方根算法
- 静态代理和动态代理
- BootstrapSouce的排版+响应式导航
- ListView中CheckBox复用问题
- 黑盒测试——错误推测法
- Android_project目录及文件详解
- 【学习笔记】快速平方根倒数算法
- 数控进入数控显示实体四轴四面Cube应用软件开发
- curl模拟请求、登陆以及带验证码登陆
- MySQL 基础使用方式
- 200多个js技巧代码
- sqlite 数据库
- 腾讯2016校招笔试题
- js数组的方法
- TUIO学习笔记1-TUIO 1.1 Protocol Specification协议规范/标准