|
发表于 2010-2-17 20:01:59
|
显示全部楼层
在keil下仿真:
//STM32@72M
float InvSqrt(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating value
i = 0x5f375a86- (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
return x;
}
int main(void)
{
u8 temp;
float testnum=3.1;
float res,res1;
Stm32_Clock_Init(9);//系统时钟设置 12M*6=72M
delay_init(72); //延时初始化
uart_init(72,57600);//串口1初始化
res=InvSqrt(testnum); //时间:0.00095323
res1=1/sqrt(testnum); //时间:0.00095551
printf("res:%f",res); //时间:0.00096559
printf("res1:%f",res1);
得到的结果:res:0.567654
res1:0.5679619
windows计算结果:0.5679618
可以看出InvSqrt的计算只花了2.28us,而第二个res1使用sqrt函数,使用时间为10.08us
后者是前者的4.42倍!!
有时候还是很有用的,这个函数.
只能感叹数学真的很神奇!
接着楼主的意思,楼主得到的是1/sqrt,我们很多时候只要SQRT就够了,并不需要倒数
所以网上又搜到以快速sqrt的函数:
float CarmSqrt(float x)
{
union
{
int intPart;
float floatPart;
} convertor;
union
{
int intPart;
float floatPart;
} convertor2;
convertor.floatPart = x;
convertor2.floatPart = x;
convertor.intPart = 0x1FBCF800 + (convertor.intPart >> 1);
convertor2.intPart = 0x5f3759df - (convertor2.intPart >> 1);
return 0.5f*(convertor.floatPart + (x * convertor2.floatPart));
}
再次来验证速度:
float InvSqrt(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
return x;
}
float CarmSqrt(float x)
{
union
{
int intPart;
float floatPart;
} convertor;
union
{
int intPart;
float floatPart;
} convertor2;
convertor.floatPart = x;
convertor2.floatPart = x;
convertor.intPart = 0x1FBCF800 + (convertor.intPart >> 1);
convertor2.intPart = 0x5f3759df - (convertor2.intPart >> 1);
return 0.5f*(convertor.floatPart + (x * convertor2.floatPart));
}
//STM32@72M
int main(void)
{
u8 temp;
float testnum=3.1;
float res,res1,res2;
Stm32_Clock_Init(9);//系统时钟设置 12M*6=72M
delay_init(72); //延时初始化
uart_init(72,57600);//串口1初始化
res=CarmSqrt(testnum); //0.00095335
res2=1/InvSqrt(testnum); //0.00095492
res1=sqrt(testnum); //0.00095791
printf("res:%f",res); //0.00096533
printf("res2:%f",res2);
printf("res1:%f",res1);
通过上面比较,CarmSqrt函数计算时间为1.57us,1/InvSqrt计算时间为:2.99us,系统sqrt函数的计算时间为:7.42us.
看出来CarmSqrt函数的性能在开平方的时候,最好了.
以后,可以试试这个,精度在10的-3次方内,这个函数可以节约很多时间. |
|