【概述】

越底层的函数,调用越频繁,那么最底层的数学运算函数的优化至关重要。

当求逆平方根时,一般做法都是用函数返回 1/sqrt(x),但在 雷神之锤3 中,有一快速求逆平方根的算法。

【知识储备】

1.单精度浮点数的存储

在计算机中,单精度浮点数使用 32 位来存储,其中,最高位为符号位,后面 8 位为整数位 ,代表浮点数的指数,再后面 23 位代表小数部分 ,依次表示 、...

因此,如果 x 是一个正浮点数,则有:

如果想将一浮点数转为整数形式,则需要做如下运算:

其中,L 是指数部分唯一需要的次数,M 是小数部分对应的整数版本,B 为 127

2.牛顿迭代法

牛顿迭代法,是求解任意连续函数的根值的一种方法。

对于如上函数,现要求这个函数的根:首先猜一个 ,假设它是函数的解,但由于其实际不是,因此需要将这个解迭代,使其逼近真正的解。

在  处作其切线,求得切线方程:,并求切线的根,可以发现对于真正的解已经逼近了一步。

推广到 n,继续迭代,就足够逼近真正的解:

此时, 可被一个统一的函数来表示:

令 ε 为当前解与真正解 r 的距离,则:

综合方程,可得:

因此,只要 ε 小于某个特定的值,则可认为此时的  与方程的解十分接近

【源码】

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 hackingi = 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;
}

【分析】

如果要求一个浮点数的平方根倒数,一般求法为:

将其转化为关于 y 的方程,有:

转换为牛顿迭代法的方程,有:

此时,对原方程两边同取 2 的对数,有:

由于 ,则在这个区间内,可以近似取: 

根据方差的计算,当 σ=0.0430357 时,整体的偏差是最小的,此时上面的等号两边应该相当。

将上述公式整合,最终的  可以写成:

则:

其中:

最终,写成代码就是:

i = 0x5f3759df - ( i >> 1 );

【关于源码】

求逆平方根的算法来自 雷神之锤3(quake3) 的作者卡马克,该算法并不复杂,其核心就是用牛顿迭代法来不断逼近,但卡马克真正厉害的地方,在于他选择了一个十分神秘的常数:0x5f3759df 来计算猜测值,于是第一次牛顿迭代算出的值已经非常接近  ,这样仅需两次牛顿迭代就可达到所需精度。

普渡大学的数学家 Chris Lomont 看了以后觉得有趣,决定要研究卡马克弄出来的这个猜测值有什么奥秘。

Lomont 在精心研究之后从理论上也推导出一个最佳猜测值:0x5f37642f,和卡马克的数字非常接近。

传奇并没有在这里结束。

Lomont 计算出结果以后非常满意,于是拿自己计算出的起始值和卡马克的神秘数字做比较,看哪个数字能够更快更精确的求得逆平方根,结果是卡马克赢了... 谁也不知道卡马克是怎么找到这个数字的。

最后 Lomont 采用暴力方法一个数字一个数字试过来,终于找到一个比卡马克数字要好上那么一丁点的数字,虽然实际上这两个数字所产生的结果非常近似,这个暴力得出的数字是:0x5f375a86。

Lomont 为此写下一篇论文,"Fast Inverse Square Root"。

论文下载地址:
http://www.math.purdue.edu/~clomont/Math/Papers/2003/InvSqrt.pdf
http://www.matrix67.com/data/InvSqrt.pdf

数学 —— 其他 —— 快速求逆平方根相关推荐

  1. 计算机与数学 —— 雷神之锤3源码中的快速逆平方根算法

    这篇博客介绍了在雷神之锤3源代码中快速求逆平方根的算法. 源码 雷神之锤3中的逆平方根算法如下: float Q_rsqrt( float number ) { long i; float x2, y ...

  2. pb实现简单计算器的思想_人教版初中数学七年级下册 用计算器求算数平方根、用有理数估计算数平方根的大小公开课优质课课件教案视频...

    6.1 用计算器研究平方根和立方根 一.教学目标 1.会用计算器求平方根和立方根,培养学生的数感. 2.经历运用计算器探究数学规律的活动,发展学生的探究能力和合情推理的能力,并在概念的探索过程中,进一 ...

  3. 【学习笔记】使用魔数快速求平方根

    [学习笔记]使用魔数快速求平方根 简介 介绍使用魔数0x1fbd1df5快速求平方根x{\sqrt{x}}x​的C语言实现和公式的推导. 代码 float MagicSqrt(float x) {fl ...

  4. 3D数学之矩阵的各种求逆

    经过三天的准备终于把矩阵的各种求逆方法以及代码完成了.心里有点小激动,come on,来吧,点燃你的心中的那团火,跟着游戏音乐的律动一起跟我走入神秘的3D世界. 下面介绍三种方法: 1.用伴随矩阵求逆 ...

  5. 【知识总结】多项式全家桶(一)(NTT、加减乘除和求逆)

    我这种数学一窍不通的菜鸡终于开始学多项式全家桶了-- 必须要会的前置技能:FFT(不会?戳我:[知识总结]快速傅里叶变换(FFT)) 以下无特殊说明的情况下,多项式的长度指多项式最高次项的次数加\(1 ...

  6. python求极限中有算术平方根如何表达_Python求算数平方根和约数的方法汇总

    Python求算数平方根和约数的方法汇总 一.求算术平方根 a= x=int(raw_input('Enter a number:')) if x >= : while a*a < x: ...

  7. CF438E The Child and Binary Tree(有意思的生成函数 + 多项式求逆 + 多项式开方)

    整理的算法模板合集: ACM模板 点我看多项式全家桶(●^◡_◡◡​^●) CF438E The Child and Binary Tree 简单的黑题 首先我们发现模数为99824435399824 ...

  8. luogu P4725 多项式对数函数 (模板题、FFT、多项式求逆、求导和积分)

    luogu P4725 多项式对数函数 (模板题.FFT.多项式求逆.求导和积分) 手动博客搬家: 本文发表于20181125 13:25:03, 原地址https://blog.csdn.net/s ...

  9. 矩阵乘法如何去逆矩阵_矩阵乘法和求逆

    矩阵乘法如何去逆矩阵 数据科学与机器学习的线性代数 (LINEAR ALGEBRA FOR DATA SCIENCE AND MACHINE LEARNING) We are going to tre ...

最新文章

  1. 李飞飞谈AI医疗:为什么我要从监督医生洗手开始做起?
  2. linux导出文件夹到u盘,Linux系统放到U盘上直接在U盘上运行Linux
  3. POJ - 3662 Telephone Lines(分层图最短路)
  4. Netcdf对数据进行裁剪
  5. java生成flash_web-flash发布了代码生成插件
  6. 商业银行如何进行分布式数据库选型思考
  7. groupby索引有效吗_两千字揭密 MySQL 8.0.19 三大索引新功能
  8. jQuery.treetable使用及异步加载
  9. 网规之路——强化项目管理知识点训练
  10. Python 3.8.7安装教程
  11. 信息安全技术第五章应用安全(完整详细笔记)
  12. 错误1406.无法将数值写入键/Software/Classess/.htm/OpenWithList/devenv.exer的解决方案
  13. 计算机硬盘隐,终极电脑磁盘隐藏方法大全
  14. 有没有java自编歌曲_简易音乐播放器制作
  15. CSDN联合安恒信息 共同发布安全开发工程师能力标准
  16. 牛客网 - [牛客OI周赛7-普及组]救救兔子(二分)
  17. 喂养三种宠物:猫、狗和鸟
  18. Node入门 (转载)--个人觉得写的不错,赞!
  19. Trac中的Ticket系统
  20. jetty服务器使用jersey作为Restful框架

热门文章

  1. 北大教授李忠:谁说学数学只是为了升学?数学可以让你受益终生!
  2. 当Typora开始收费,开源免费的MarkText编辑器火了:一周新增2k+star
  3. 消息队列 ActiveMQ 、RocketMQ 、RabbitMQ 和 Kafka 如何选择?
  4. JEECG第二期深入使用培训(报名截止2014-06-21)
  5. Maven系列2--pom.xml 配置详解
  6. 编程体系结构(09):分布式系统架构
  7. SpringBoot2 集成日志,复杂业务下的自定义实现
  8. Spark家族:Win10系统下搭建Scala开发环境
  9. 【跃迁之路】【706天】程序员高效学习方法论探索系列(实验阶段463-2019.1.26-27)...
  10. 2.3Python基础语法(三)之输入输出