看看这段神奇的快速开平方并取倒数代码:
-
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;
- }
下面为我编写的简单测试代码:
-
#include "stdafx.h"
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <windows.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()
- {
-
// 比较精度
-
float val = 0.0f;
- val = 1.0f;
-
printf("计算精度比较: \n");
-
printf("输入值: %f 快速算法: %f VC函数: %f \n", val, InvSqrt(val), 1.0f / sqrt(val));
- val = 16.0f;
-
printf("输入值: %f 快速算法: %f VC函数: %f \n", val, InvSqrt(val), 1.0f / sqrt(val));
- val = 25.0f;
-
printf("输入值: %f 快速算法: %f VC函数: %f \n", val, InvSqrt(val), 1.0f / sqrt(val));
- val = 100.0f;
-
printf("输入值: %f 快速算法: %f VC函数: %f \n", val, InvSqrt(val), 1.0f / sqrt(val));
-
printf("\n计算性能比较: \n");
-
int count = 1000000;
-
DWORD timeStart = 0, timeEnd = 0;
- timeStart = GetTickCount();
-
for (int i = 0; i < count; i++)
- {
- val = InvSqrt(100.0f);
- }
- timeEnd = GetTickCount();
-
printf("快速算法耗时: %f \n", (timeEnd - timeStart) * 0.001);
- timeStart = GetTickCount();
-
for (int i = 0; i < count; i++)
- {
- val = 1.0f / sqrt(100.0f);
- }
- timeEnd = GetTickCount();
-
printf("VC函数耗时: %f \n", (timeEnd - timeStart) * 0.001);
-
printf("\n");
-
system("pause");
-
return 0;
- }
这里与sqrt()分别比较了计算精度及计算性能,测试环境为vs2005,普通pc笔记本(其实是一台年久的、玩的了游戏、写得了代码的小黑)。从对比结果看,该快速算法在计算结果上有一点点误差,但是计算性能上很可观。下图为对比结果: