#include<stdio.h>
#include<string.h>
#include <stdlib.h> /* atof */ /*
计算=1/sqrt(n)
*/
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;
} int main(int argc, char const *argv[])
{
float f9 = 81.0f;
f9 = Q_rsqrt(f9); printf("f9=%f\n", f9); return 0;
}

  运行结果:

f9=0.111086

和计算机1/sqrt(81)很接近1/9=0.111111

相比 sqrt() 函数,这套算法要快将近4倍,要知道,编译器自带的函数,可是经过严格仔细的汇编优化的啊!

牛顿迭代法的原理是先猜测一个值,然后从这个值开始进行叠代。因此,猜测的值越准,叠代的次数越少。卡马克选了0x5f3759df这个值作为猜测的结果,再加上后面的移位算法,得到的y非常接近1/sqrt(n)。这样,我们只需要2次牛顿迭代法就可以达到我们所需要的精度。

函数返回1/sqrt(x),这个函数在图像处理中比sqrt(x)更有用。

注意到这个正数只用了一次叠代!(其实就是根本没用叠代,直接运算)。编译、实验,这个团数不仅工作的很好,而且比标准的sqrt()函数快4倍!

这个简洁的定数,最核心,也是最让人费解的,就是标注了what the fuck的一句 i   = 0x5f3759df - ( i >> 1 );再加上y   = y * ( threehalfs - ( x2 * y * y ) )。

两句话就完成了开方运算!而且注意到,核心那句是移位运算,速度极快!特别在很多没有乘法指令的RISC结构CPU上,这样做是极其高效的。

算法的原理就是使用牛顿迭代法,用 x-f(x)/f'(x) 来不断的逼近 f(x)=a 的根。

求平方根:f(x)=x^2=a ,f'(x)= 2*x, f(x)/f'(x)=x/2,把 f(x) 代入 x-f(x)/f'(x)后有(x+a/x)/2,

现在我们选 a=5,选一个猜测值比如 2,  那么我们可以这么算  5/2 = 2.5; (2.5+2)/2 = 2.25; 5/2.25 = ……  这样反复迭代下去,结果必定收敛于 sqrt(5)。

但是卡马克作者真正厉害的地方是他选择了一个神秘的常数 0x5f375a86来计算那个梦“值,

就是我们加注释的那一行那行算出的值非常接近1/sqrt(n)这样我们只需要2次牛顿迭代就可以达到我们所需要的精度。

快速开平方取倒数的算法--嵌入式ARM转载的更多相关文章

  1. 用C语言将一个数开根号后再取倒数的方法

    在上学的时候,曾经看过有人写过这样的算法,就是将一个数开根号后再取倒数的算法,我本人也觉得十分巧妙,于是就将它积累了下来,让我们来看看是怎么回事: #include <stdio.h> # ...

  2. HDU--杭电--4506--小明系列故事——师兄帮帮忙--快速幂取模

    小明系列故事——师兄帮帮忙 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) To ...

  3. 【转】C语言快速幂取模算法小结

    (转自:http://www.jb51.net/article/54947.htm) 本文实例汇总了C语言实现的快速幂取模算法,是比较常见的算法.分享给大家供大家参考之用.具体如下: 首先,所谓的快速 ...

  4. HDU 1061 Rightmost Digit --- 快速幂取模

    HDU 1061 题目大意:给定数字n(1<=n<=1,000,000,000),求n^n%10的结果 解题思路:首先n可以很大,直接累积n^n再求模肯定是不可取的, 因为会超出数据范围, ...

  5. Fast InvSqrt()(平方根倒数速算法)

    浮点数的平方根倒数常用于计算正规化矢量.3D图形程序需要使用正规化矢量来实现光照和投影效果,因此每秒都需要做上百万次平方根倒数运算,而在处理坐标转换与光源的专用硬件设备出现前,这些计算都由软件完成,计 ...

  6. Powmod快速幂取模

    快速幂取模算法详解 1.大数模幂运算的缺陷: 快速幂取模算法的引入是从大数的小数取模的朴素算法的局限性所提出的,在朴素的方法中我们计算一个数比如5^1003%31是非常消耗我们的计算资源的,在整个计算 ...

  7. 洛谷 P1226 【模板】快速幂||取余运算

    题目链接 https://www.luogu.org/problemnew/show/P1226 题目描述 输入b,p,k的值,求b^p mod k的值.其中b,p,k*k为长整型数. 输入输出格式 ...

  8. 《Java语言实现快速幂取模》

    快速幂取模算法的引入是从大数的小数取模的朴素算法的局限性所提出的,在朴素的方法中我们计算一个数比如5^1003%31是非常消耗我们的计算资源的,在整个计算过程中最麻烦的就是我们的5^1003这个过程 ...

  9. 二分求幂/快速幂取模运算——root(N,k)

    二分求幂 int getMi(int a,int b) { ; ) { //当二进制位k位为1时,需要累乘a的2^k次方,然后用ans保存 == ) { ans *= a; } a *= a; b / ...

随机推荐

  1. Coursera,Udacity,Edx 课程列表(更新ing)

    Coursera,Udacity,Edx 课程列表(更新ing) Coursera有很多特别好的课程,平时没有机会听到国外大牛的课程,通过Coursera算是可以弥补一下吧,国外的课程普遍比国内的老师 ...

  2. UML概念模型

    UML概念模型 UML(Unified Modeling Language):统一建模语言,为面向对象开发系统的产品进行说明.可视化.和编制文档的标准语言 面向对象程序设计 面向对象基本概念:对象.类 ...

  3. css中常用的选择器和选择器优先级

    css常用的选择器:类选择器,id选择器,元素选择器,伪类选择器,伪元素选择器,属性选择器. 选择器的优先级由四个部分组成:0,0,0,0 一个选择器的具体优先级如下规则确定: ID选择器 加 0,1 ...

  4. pt-archiver 归档历史数据及参数详解

    目录 1. 背景 2. 操作步骤 2.1. 确认数据归档条件,此次操作开发按照非主键列 server_time 按时间进行删除并保存,需要转化为主键列条件. 2.2. 由于历史表文件较大,按月归档.删 ...

  5. javascript 代码实例

    数组去重 function unique(arr){ if(!Array.isArray(arr)){ console.log('type error!'); return; } arr = arr. ...

  6. spring-data-jpa模糊查询

    记录一条关于spring-data-jpa模糊查询的语句 方法一: @Query(value="select * from search_key a where a.key_name lik ...

  7. quartz2.3.0(四)JobDataMap—带状态集合的定时器内置集合

    任务类 package org.quartz.examples.example4; import java.util.Date; import org.quartz.DisallowConcurren ...

  8. redis客户端介绍及php客户端的下载安装

    一.PHP客户端1.官方提供了几款PHP客户端,包括amphp/redis.phpredis.Predis.Rediska.推荐使用官方推荐的两款客户端,phpredis.Predis2.phpred ...

  9. Unity项目 - 坦克大战3D TankBattle

    目录 游戏原型 项目演示 绘图资源 代码实现 技术探讨 参考来源 游戏原型 游戏玩法:在有界的战场上,玩家将驾驶坦克,代表绿色阵营,与你的队友一起击溃红蓝阵营的敌人,在这场三方大战中夺得胜利! 操作指 ...

  10. Navicat 连接mysql 报错: Authentication plugin caching_ sha2_password cannot be loaded

    出现这个错误的时候, 网上的资料都是修改mysql的登录信息的, ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password ...