在嵌入式设备中,浮点数的计算十分缓慢,sin与cos函数的计算更是缓慢。
如果想提速,对于sin与cos,可以用查表法与泰勒展开。查表法更快一点,但如果想提高精度,就要加大表的体积,需要占用更多空间。
总而言之,各有优劣。如果不追求超高精度,同时有足够的内存来存放表格,查表法显然更快。
1、查表法:
待编写
创建查表法所用的表格,C程序如下:
#include<math.h>
#include<stdio.h>
#define PI 3.14159265358979323846
int main()
{
FILE* fp = NULL;
float fAccuracy;
float fRad = 0;
unsigned int iCount = 0;
fp = fopen("E:/SinTable.txt", "w");
fAccuracy = 0.0016;
while (fRad < PI / 2)
{
fprintf(fp, "%.5f, ", sin(fRad));
//fprintf(fp, "%d, ", (int)(sin(fRad) * 8192 + 0.5)); //如果要获取整数表格,注意将浮点型转整型时,会向下取整,所以必须+0.5
fRad += fAccuracy;
iCount++;
if (iCount % 50 == 0)
{
fprintf(fp, "\n");
}
}
fclose(fp);
return 0;
}
注意:如果要获取整数表格,注意将浮点型转整型时,会向下取整,所以在转整型前必须加0.5。
int SinLookupTable(int radMUL625) //addrin is rad, must alredy multiply 200
{
int8_t i8PNflag = 1;
while (radMUL625 > TWO_PI) //大于360度
{
radMUL625 = radMUL625 - TWO_PI;
}
while (radMUL625 < 0) // 小于0度
{
radMUL625 = radMUL625 + TWO_PI;
}
if (radMUL625 > HALF_PI && radMUL625 <= ONE_PI) //大于90度, 小于180度
{
radMUL625 = ONE_PI- radMUL625;
i8PNflag = 1;
}
else if (radMUL625 > ONE_PI && radMUL625 <= ONEHALF_PI) //大于180度,小于270度 3 / 2 * PI * ACCURACY
{
radMUL625 = radMUL625 - ONE_PI;
i8PNflag = -1;
}
else if (radMUL625 > ONEHALF_PI && radMUL625 <= TWO_PI) //大于270度,小于360度 addrin > 3 / 2 * PI * ACCURACY
{
radMUL625 = TWO_PI - radMUL625;
i8PNflag = -1;
}
return (i8PNflag * u16SinHalfPiTable[radMUL625]);
}
int CosLookupTable(int radMUL625) //addrin is rad, must alredy multiply 200
{
return SinLookupTable(radMUL625 + HALF_PI);
}
2、泰勒展开展开法:
#define CV_PI 3.14159265359
#define halfPi ((float)(CV_PI*0.5))
#define Pi ((float)CV_PI)
#define a0 0 /*-4.172325e-7f*/ /*(-(float)0x7)/((float)0x1000000); */
#define a1 1.000025f /*((float)0x1922253)/((float)0x1000000)*2/Pi; */
#define a2 -2.652905e-4f /*(-(float)0x2ae6)/((float)0x1000000)*4/(Pi*Pi); */
#define a3 -0.165624f /*(-(float)0xa45511)/((float)0x1000000)*8/(Pi*Pi*Pi); */
#define a4 -1.964532e-3f /*(-(float)0x30fd3)/((float)0x1000000)*16/(Pi*Pi*Pi*Pi); */
#define a5 1.02575e-2f /*((float)0x191cac)/((float)0x1000000)*32/(Pi*Pi*Pi*Pi*Pi); */
#define a6 -9.580378e-4f /*(-(float)0x3af27)/((float)0x1000000)*64/(Pi*Pi*Pi*Pi*Pi*Pi); */
#define SinTaylor(x) ((((((a6*(x) + a5)*(x) + a4)*(x) + a3)*(x) + a2)*(x) + a1)*(x) + a0)
#define CosTaylor(x) SinTaylor(halfPi - (x))