算法学习笔记(二):平方根倒数速算法

这是一个神奇的算法!


一、介绍

起源于一篇《改变计算技术的伟大算法》文章,知道这个算法,然后google一下,维基讲的还不错,本文权当自己理清下思路。先贴源代码,为《雷神之锤III竞技场》源代码中的应用实例,剥离了C语言预处理器的指令,并附上了原有的注释。

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(对浮点数的邪恶位级hack)
	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(第二次迭代,可以删除)
 
	return y;
}

算法的思路:

1、计算出该浮点数的平方根倒数的首次近似值,见源代码中的8-11行

2、利用牛顿法迭代以加强精度,得到要求精度内的值(迭代次数根据精度要求调整,源代码中一次迭代就满足精度要求)

算法的巧妙之处在于代码中的四行蓝色代码,大致过程是:将表示浮点数的字节序列用来表示整数(i  = * ( long * ) &y;),然后通过一个巧妙的整数运算得到一个新的整数(i  = 0x5f3759df - ( i >> 1 );),最后将表示整数的字节序列换回表示浮点数。所以弄清算法关键障碍是:在计算机中是如何表示浮点数和整数的、整数运算又怎能算出浮点数的平方根倒数的近似值、0x5f3759df怎么来的。 


二、浮点数和整数的表示方法

浮点数和整数存储位数一定是相同的这里浮点数和整数都占4字节,32位。

一个浮点数是由32位二进制位表示的有理数,分为三部分。其中符号1位,表示正负,记为Si指数占接下来的8位,表示经过偏移处理后的指数,即实际表示E(如图中为124),需要偏移B(图中为2的8次方减1,127。B为一个固定值),最后得指数值为E-B有效数字(除最高位以外)占剩下的23位,记为m(0<m<1),图中的\scriptstyle m=1\times 2^{-2}=0.250

所以浮点数的结构公式为:\scriptstyle x=(-1)^{\mathrm{Si}}\cdot(1+m)\cdot 2^{(E-B)},  图中 \scriptstyle x=(1+0.250)\cdot 2^{-3}=0.15625


整数的表示相对简单,符号占1位,数值占剩下的31位。如果用上图的浮点数字节序列来表示整数,那么

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值