cream 的qsqrt 及其原理
首先,是creamk 的qsort:
- 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.0/sqrt(x);
以及c++中简单的实现代码:
1
2
3
4
5
6
7
8
9
10
11
12
|
static float CarmackSqrt ( float x) { float xhalf = 0.5f * x; int i = *( int *)&x; // get bits for floating VALUE i = 0x5f3759df - (i>>1); // gives initial guess y0 x = *( float *)&i; // convert bits BACK to float x = x*(1.5f - xhalf*x*x); // Newton step, repeating increases accuracy x = x*(1.5f - xhalf*x*x); // Newton step, repeating increases accuracy x = x*(1.5f - xhalf*x*x); // Newton step, repeating increases accuracy return (1 / x); } |
经过测试,这段代码是stl里的sqrt效率的4倍。辣么问题来了,为什么这段代码这么高效呢?
首先,creamk用了求解平方根的一般方法:牛顿迭代法,其原理如下:














,取其线性部分(即泰勒展开的前两项),并令其等于0,即

,以此作为非线性方程

的近似方程


, 这样,得到牛顿迭代法的一个迭代关系式:

。
最佳猜测值,和creamk的数字非常接近, 0x5f37642f。Lomont计算出结果以后非常满意,于是拿自己计算出的起始值和creamk的神秘数字做比赛,看看谁的数字能够更快更精确的求得平方根。结果是creamk赢了。 谁也不知道creamk是怎么找到这个数字 的。
最后Lomont发威了,采用暴力方法一个数字一个数字试过来,终于找到一个比creamk的数字效率高一些的数字,虽然实际上这两个数字所产生的结果非常近似,这个暴力得出的数字是0x5f375a86。
Lomont为此写下一篇论文,"Fast Inverse Square Root"。
在需要进行大数据量的sqrt运算时,creamk的qsqrt会比stl库中的 sqrt效率高出不知一星半点。
所以当你觉得有必要用的时候,尽情的用它吧!
cream 的qsqrt 及其原理的更多相关文章
- Volley 实现原理解析(转)
Volley 实现原理解析 转自:http://blog.csdn.net/fengqiaoyebo2008/article/details/42963915 1. 功能介绍 1.1. Volley ...
- volley请求原理
Volley 实现原理解析 本文为 Android 开源项目实现原理解析 中 Volley 部分 项目地址:Volley,分析的版本:35ce778,Demo 地址:Volley Demo 分析者:g ...
- 奇异值分解(SVD)原理与在降维中的应用
奇异值分解(Singular Value Decomposition,以下简称SVD)是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域.是 ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
- 线性判别分析LDA原理总结
在主成分分析(PCA)原理总结中,我们对降维算法PCA做了总结.这里我们就对另外一种经典的降维方法线性判别分析(Linear Discriminant Analysis, 以下简称LDA)做一个总结. ...
- [原] KVM 虚拟化原理探究(1)— overview
KVM 虚拟化原理探究- overview 标签(空格分隔): KVM 写在前面的话 本文不介绍kvm和qemu的基本安装操作,希望读者具有一定的KVM实践经验.同时希望借此系列博客,能够对KVM底层 ...
- H5单页面手势滑屏切换原理
H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路. 1.实现原理 ...
- .NET Core中间件的注册和管道的构建(1)---- 注册和构建原理
.NET Core中间件的注册和管道的构建(1)---- 注册和构建原理 0x00 问题的产生 管道是.NET Core中非常关键的一个概念,很多重要的组件都以中间件的形式存在,包括权限管理.会话管理 ...
- python自动化测试(2)-自动化基本技术原理
python自动化测试(2) 自动化基本技术原理 1 概述 在之前的文章里面提到过:做自动化的首要本领就是要会 透过现象看本质 ,落实到实际的IT工作中就是 透过界面看数据. 掌握上面的这样的本领 ...
随机推荐
- Warning: File upload error - unable to create a temporary file in Unknown on line 0
upload_tmp_dir 临时文件夹问题 上传文件提示 Warning: File upload error - unable to create a temporary file in Unkn ...
- JS 控制页面刷新
.页面自动刷新:把如下代码加入<head>区域中 <meta http-equiv=">,其中20指每隔20秒刷新一次页面. .页面自动跳转:把如下代码加入<h ...
- deepin 快捷键
从此脱离鼠标
- /proc/diskstats文件注解
/proc/diskstats 注解 今儿在准备利用shell监控磁盘读写次数等信息时,看到该文件,但是又不清楚每段的具体含义,这里备注下. 文件内容 [root@namenode proc]# ca ...
- Linux内核堆栈使用方法 进程0和进程1【转】
转自:http://blog.csdn.net/yihaolovem/article/details/37119971 目录(?)[-] 8 Linux 系统中堆栈的使用方法 81 初始化阶段 82 ...
- python中eval函数使用
把字符串转换为字典: s = "{'a':1}" eval(s)
- 生命周期(vue的钩子函数)
生命周期图示 创建前,创建后,挂载前,挂载后,更新前,更新后,销毁前,销毁后 beforeCreate:function(){ console.log('1-beforeCreate 组件还未被创建' ...
- 16:django 有条件的视图处理(Last-Modified和ETag)&&加密签名
有条件的视图处理 上一节我们介绍了缓存来减轻服务器的负担,这里的有条件的视图处理也从一定程度上减轻了服务器的负担,在正式介绍之前,先来看两个概念:Last-Modified和ETag Last-Mod ...
- linux命令(23):cp命令
实例一:复制单个文件到目标目录 cp 1.log /home 说明: 1.在没有带-a参数时,两个文件的时间是不一样的.在带了-a参数时,两个文件的时间是一致的. 2.当目标文件已存在,会询问是否覆盖 ...
- transition结合:after,:before实现动画
div代码 <div class='div'> hover </div> css代码 .div{ width:200px; height:100px; line-height: ...