Carmack的Inverse Square Root( 就是1/sqrt(x) )的函数

Carmack的逆平方根算法
文章介绍了John Carmack为提高Quake III性能而设计的一种高效计算逆平方根的方法。这种方法通过巧妙利用浮点数的位级表示,并结合简单的迭代公式,在牺牲少量精度的情况下获得了极大的速度提升。

大概意思,在QuakeIII的源代码里,有1个求Inverse Square Root( 就是1/sqrt(x) )的函数,
Carmack实现的算法在有的CPU上,比正常的(float)(1.0/sqrt(x))快了4倍!(上面这个表达式里的sqrt(x)还是直接调汇编指令fsqrt来算的!!!)

Carmack的代码如下:

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

实际上就是Newton法迭代,但Carmack使用了一个神秘的常数,0x5f3759df,只迭代一次就求出了结果.

Purdue大学的Chris Lomont写了一篇论文http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf,他在里面用数学方法推导出了一个常数0x5f37642f,跟Carmack的稍有不同,效果也没有Carmack的好.

天才就是天才啊,Carmack不过才是high school毕业吧.

在3D图形编程中,经常要求平方根或平方根的倒数,例如:求向量的长度或将向量归一化。C数学函数库中的sqrt具有理想的精度,但对于3D游戏程式来说速度太慢。我们希望能够在保证足够的精度的同时,进一步提高速度。 Carmack在QUAKE3中使用了下面的算法,它第一次在公众场合出现的时候,几乎震住了所有的人。据说该算法其实并不是Carmack发明的,它真正的作者是Nvidia的Gary Tarolli(未经证实)。 此算法让计算平方根倒数的计算速度提高了4倍,导致了3D游戏的革命。没有这个算法,恐怕到现在3D游戏里的物体仍然没影子(想想看CS的画面)。 这个算法在上世纪就出现了,但是在10年前才引起游戏圈的关注,算法的原理很清楚,但是作为算法核心的那个常数0x5f3759df,至今没人知道它是怎么得出来的。有传言说是外星人入侵互联网时留下了这个常数。 // // 计算参数x的平方根的倒数 // float InvSqrt (float x) { float xhalf = 0.5f*x; int i = *(int*)&x; i = 0x5f3759df - (i >> 1); x = *(float*)&i; x = x*(1.5f - xhalf*x*x); return x; } 如果要求某个浮点数x的平方根倒数,请问用C数学函数库中的sqrt函数和用以上InvSqrt函数求得的结果的误差的绝对值是多少? 输入 先输入一个整数n,表示有n组测试数据。 此后每行输入一个浮点数x。 输出 C数学函数库中的sqrt函数和用以上InvSqrt函数求得x的平方根倒数,输出两个结果误差的绝对值,精确到小数点后6位。
最新发布
11-03
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值