【C语言作业】外星语言

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函数求得的结果的误差的绝对值是多少?

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
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;
}
int main()
{
 int n;
 float x;
 scanf("%d",&n);
 for(int i =0;i<n;i++)
 {   
  scanf("%f",&x);
  printf("%f\n",fabs(1.0/sqrt(x)-InvSqrt(x)));
 }
 return 0;
}

猜你喜欢

转载自www.cnblogs.com/asher0608/p/11689461.html