数学 —— 其他 —— 快速求逆平方根
【概述】
越底层的函数,调用越频繁,那么最底层的数学运算函数的优化至关重要。
当求逆平方根时,一般做法都是用函数返回 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
数学 —— 其他 —— 快速求逆平方根相关推荐
- 计算机与数学 —— 雷神之锤3源码中的快速逆平方根算法
这篇博客介绍了在雷神之锤3源代码中快速求逆平方根的算法. 源码 雷神之锤3中的逆平方根算法如下: float Q_rsqrt( float number ) { long i; float x2, y ...
- pb实现简单计算器的思想_人教版初中数学七年级下册 用计算器求算数平方根、用有理数估计算数平方根的大小公开课优质课课件教案视频...
6.1 用计算器研究平方根和立方根 一.教学目标 1.会用计算器求平方根和立方根,培养学生的数感. 2.经历运用计算器探究数学规律的活动,发展学生的探究能力和合情推理的能力,并在概念的探索过程中,进一 ...
- 【学习笔记】使用魔数快速求平方根
[学习笔记]使用魔数快速求平方根 简介 介绍使用魔数0x1fbd1df5快速求平方根x{\sqrt{x}}x的C语言实现和公式的推导. 代码 float MagicSqrt(float x) {fl ...
- 3D数学之矩阵的各种求逆
经过三天的准备终于把矩阵的各种求逆方法以及代码完成了.心里有点小激动,come on,来吧,点燃你的心中的那团火,跟着游戏音乐的律动一起跟我走入神秘的3D世界. 下面介绍三种方法: 1.用伴随矩阵求逆 ...
- 【知识总结】多项式全家桶(一)(NTT、加减乘除和求逆)
我这种数学一窍不通的菜鸡终于开始学多项式全家桶了-- 必须要会的前置技能:FFT(不会?戳我:[知识总结]快速傅里叶变换(FFT)) 以下无特殊说明的情况下,多项式的长度指多项式最高次项的次数加\(1 ...
- python求极限中有算术平方根如何表达_Python求算数平方根和约数的方法汇总
Python求算数平方根和约数的方法汇总 一.求算术平方根 a= x=int(raw_input('Enter a number:')) if x >= : while a*a < x: ...
- CF438E The Child and Binary Tree(有意思的生成函数 + 多项式求逆 + 多项式开方)
整理的算法模板合集: ACM模板 点我看多项式全家桶(●^◡_◡◡^●) CF438E The Child and Binary Tree 简单的黑题 首先我们发现模数为99824435399824 ...
- luogu P4725 多项式对数函数 (模板题、FFT、多项式求逆、求导和积分)
luogu P4725 多项式对数函数 (模板题.FFT.多项式求逆.求导和积分) 手动博客搬家: 本文发表于20181125 13:25:03, 原地址https://blog.csdn.net/s ...
- 矩阵乘法如何去逆矩阵_矩阵乘法和求逆
矩阵乘法如何去逆矩阵 数据科学与机器学习的线性代数 (LINEAR ALGEBRA FOR DATA SCIENCE AND MACHINE LEARNING) We are going to tre ...
最新文章
- 李飞飞谈AI医疗:为什么我要从监督医生洗手开始做起?
- linux导出文件夹到u盘,Linux系统放到U盘上直接在U盘上运行Linux
- POJ - 3662 Telephone Lines(分层图最短路)
- Netcdf对数据进行裁剪
- java生成flash_web-flash发布了代码生成插件
- 商业银行如何进行分布式数据库选型思考
- groupby索引有效吗_两千字揭密 MySQL 8.0.19 三大索引新功能
- jQuery.treetable使用及异步加载
- 网规之路——强化项目管理知识点训练
- Python 3.8.7安装教程
- 信息安全技术第五章应用安全(完整详细笔记)
- 错误1406.无法将数值写入键/Software/Classess/.htm/OpenWithList/devenv.exer的解决方案
- 计算机硬盘隐,终极电脑磁盘隐藏方法大全
- 有没有java自编歌曲_简易音乐播放器制作
- CSDN联合安恒信息 共同发布安全开发工程师能力标准
- 牛客网 - [牛客OI周赛7-普及组]救救兔子(二分)
- 喂养三种宠物:猫、狗和鸟
- Node入门 (转载)--个人觉得写的不错,赞!
- Trac中的Ticket系统
- jetty服务器使用jersey作为Restful框架
热门文章
- 北大教授李忠:谁说学数学只是为了升学?数学可以让你受益终生!
- 当Typora开始收费,开源免费的MarkText编辑器火了:一周新增2k+star
- 消息队列 ActiveMQ 、RocketMQ 、RabbitMQ 和 Kafka 如何选择?
- JEECG第二期深入使用培训(报名截止2014-06-21)
- Maven系列2--pom.xml 配置详解
- 编程体系结构(09):分布式系统架构
- SpringBoot2 集成日志,复杂业务下的自定义实现
- Spark家族:Win10系统下搭建Scala开发环境
- 【跃迁之路】【706天】程序员高效学习方法论探索系列(实验阶段463-2019.1.26-27)...
- 2.3Python基础语法(三)之输入输出