测试算法对比

本文对比了STM32F103C8T6芯片上不同开方、正余弦及反正切函数的实现效率,包括自定义算法与库函数。通过代码大小和执行时间分析,探讨了各种算法的优劣。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

测试条件:

开发环境:keil4

芯片信号:STM32F103C8T6

主频:64MHZ

开方函数

1、测试math_temp1 = SquareRootFloat(5.0f);

float SquareRootFloat(float number)

{

   long i;

   float x, y;

   const float f = 1.5F;

 

    x= number * 0.5F;

   y  = number;

   i  = * ( long * ) &y;                      // evil floating point bit level hacking

   i  = 0x5f3759df - ( i >> 1);  //¿¨Âí¿Ë

 //i  = 0x5f375a86 - ( i >> 1);  //Lomont

   y  = * ( float * ) &i;

   y  = y * ( f - ( x * y * y ) ); //1st iteration

   y  = y * ( f - ( x * y * y ) ); //2nd iteration, this can be removed

   return number * y;

}

含有math_temp1 =SquareRootFloat(5.0f);代码大小如下:

Program Size: Code=25296 RO-data=1016 RW-data=572ZI-data=1564 

不含math_temp1 =SquareRootFloat(5.0f); 代码大小如下:

Program Size:Code=24764 RO-data=1012 RW-data=564 ZI-data=1052 

math_temp1 =SquareRootFloat(5.0f);代码占:532byte

执行时间:13us;执行结果:math_temp1 = 2.236068

2、测试math_temp1 = sqrt(5.0f);//函数库自带的开根号函数

含有math_temp1 =sqrt(5.0f);代码大小如下:

Program Size: Code=25080 RO-data=1016 RW-data=564ZI-data=1052    

不含math_temp1 =sqrt(5.0f); 代码大小如下:

Program Size:Code=24764 RO-data=1012 RW-data=564 ZI-data=1052 

math_temp1 = sqrt(5.0f);代码占:216byte

执行时间:41us;执行结果:math_temp1 = 2.236068

3、测试math_temp1 = _sqrt(5.0f);//函数库自带的开根号函数

含有math_temp1 =_sqrt(5.0f);代码大小如下:

Program Size: Code=25084 RO-data=1012 RW-data=564ZI-data=1052      

不含math_temp1 =_sqrt(5.0f); 代码大小如下:

Program Size:Code=24764 RO-data=1012 RW-data=564 ZI-data=1052 

math_temp1 = _sqrt(5.0f);代码占:220byte

执行时间:44us;执行结果:math_temp1 = 2.236068

Atan函数

1、  测试math_temp1 =utils_fast_atan2(6.0f, 2.0f);//非查表

floatutils_fast_atan2(float y, float x) {

float abs_y = fabsf(y) + 1e-10; // kludge toprevent 0/0 condition

float angle;

 

if (x >= 0) {

           float r = (x - abs_y) / (x + abs_y);

           float rsq = r * r;

           angle = ((0.1963 * rsq) - 0.9817) * r+ (M_PI / 4.0);

} else {

           float r = (x + abs_y) / (abs_y - x);

           float rsq = r * r;

           angle = ((0.1963 * rsq) - 0.9817) * r+ (3.0 * M_PI / 4.0);

}

 

if (y < 0) {

           return(-angle);

} else {

           return(angle);

}

}

含有math_temp1 =utils_fast_atan2(6.0f, 2.0f);代码大小如下:

         ProgramSize: Code=26144 RO-data=1016 RW-data=1600 ZI-data=1560 

不含math_temp1 =utils_fast_atan2(6.0f, 2.0f);代码大小如下:

Program Size:Code=24764 RO-data=1012 RW-data=564 ZI-data=1052 

math_temp1 =utils_fast_atan2(6.0f, 2.0f);代码占:1380byte

执行时间:32us;执行结果:math_temp1 = -0.000002

2、  测试math_temp1 = fast_atan2(6.0f,2.0f);//查表算法

REALfast_atan2(REAL y, REAL x)

{

REAL x_abs, y_abs, z;

REAL alpha, angle, base_angle;

int index;

 

/* don't divide by zero! */

if ((y == 0.0f) || (x == 0.0f))//if ((y ==0.0f) && (x == 0.0f))

           angle = 0.0f;

else

{

           /* normalize to +/- 45 degree range*/

           y_abs = my_abs(y);

           x_abs = my_abs(x);

           //z = (y_abs < x_abs ? y_abs /x_abs : x_abs / y_abs);

           if (y_abs < x_abs)

                    z = y_abs / x_abs;

           else

                    z = x_abs / y_abs;

           /* when ratio approaches the tableresolution, the angle is */

           /*      best approximated with the argumentitself...       */

           if (z < TAN_MAP_RES)

                    base_angle = z;

           else

           {

                    /* find index andinterpolation value */

                    alpha = z * (REAL)TAN_MAP_SIZE - .5f;

                    index = (int) alpha;

                    alpha -= (REAL) index;

                    /* determine base anglebased on quadrant and */

                    /* add or subtract tablevalue from base angle based on quadrant */

                    base_angle =fast_atan_table[index];

                    base_angle +=(fast_atan_table[index + 1] - fast_atan_table[index]) * alpha;

           }

 

           if (x_abs > y_abs)

           {        /* -45 -> 45 or 135 -> 225 */

                    if (x >= 0.0f)

                    {           /* -45 -> 45 */

                             if (y >= 0.0f)

                                       angle =base_angle;   /* 0 -> 45, angle OK */

                             else

                                       angle = -base_angle;  /* -45 -> 0, angle = -angle */

                    }

                    else

                    {                  /* 135 -> 180 or 180 ->-135 */

                             angle =3.14159265358979323846;

 

                             if (y >= 0.0f)

                                       angle -=base_angle;  /* 135 -> 180, angle =180 - angle */

                             else

                                       angle = base_angle- angle;   /* 180 -> -135, angle =angle - 180 */

                    }

           }

           else

           {                    /* 45 -> 135 or -135-> -45 */

                    if (y >= 0.0f)

                    {           /* 45 -> 135 */

                             angle =1.57079632679489661923;

 

                             if (x >= 0.0f)

                                       angle -=base_angle;  /* 45 -> 90, angle = 90 -angle */

                             else

                                       angle +=base_angle;  /* 90 -> 135, angle = 90+ angle */

                    }

                    else

                    {                  /* -135 -> -45 */

                             angle =-1.57079632679489661923;

 

                             if (x >= 0.0f)

                                       angle +=base_angle;  /* -90 -> -45, angle =-90 + angle */

                             else

                                       angle -=base_angle;  /* -135 -> -90, angle =-90 - angle */

                    }

           }

}

 

 

#ifdefZERO_TO_TWOPI

if (angle < 0)

           return (angle + TWOPI);

else

           return (angle);

#else

return (angle);

#endif

}

含有math_temp1 =fast_atan2(6.0f, 2.0f);代码大小如下:

Program Size: Code=26144 RO-data=1016 RW-data=1600ZI-data=1560 

不含math_temp1 =fast_atan2(6.0f, 2.0f);代码大小如下:

Program Size:Code=24764 RO-data=1012 RW-data=564 ZI-data=1052 

math_temp1 = fast_atan2(6.0f,2.0f);代码占:1380byte

执行时间:22us;执行结果:math_temp1 = 1.249635

3、  测试math_temp1 = atan2f(6.0f, 2.0f);//函数库带有的

含有math_temp1 =atan2f(6.0f, 2.0f);代码大小如下:

Program Size: Code=25620 RO-data=1012 RW-data=564ZI-data=1052 

不含math_temp1 =atan2f(6.0f, 2.0f);代码大小如下:

Program Size:Code=24764 RO-data=1012 RW-data=564 ZI-data=1052 

math_temp1 = atan2f(6.0f, 2.0f);代码占:856byte

执行时间:22us;执行结果:math_temp1 = 1.249046

 

正余弦函数

1、测试正余弦函数utils_fast_sincos_better(2.0f,&s,&c);//本杰明

voidutils_fast_sincos_better(float angle, float *sin, float *cos) {

//always wrap input angle to -PI..PI

while (angle < -M_PI) {

           angle += 2.0 * M_PI;

}

 

while (angle >  M_PI) {

           angle -= 2.0 * M_PI;

}

 

//compute sine

if (angle < 0.0) {

           *sin = 1.27323954 * angle +0.405284735 * angle * angle;

 

           if (*sin < 0.0) {

                    *sin = 0.225 * (*sin * -*sin- *sin) + *sin;

           } else {

                    *sin = 0.225 * (*sin * *sin- *sin) + *sin;

           }

} else {

           *sin = 1.27323954 * angle -0.405284735 * angle * angle;

 

           if (*sin < 0.0) {

                    *sin = 0.225 * (*sin * -*sin- *sin) + *sin;

           } else {

                    *sin = 0.225 * (*sin * *sin- *sin) + *sin;

           }

}

 

// compute cosine: sin(x + PI/2) = cos(x)

angle += 0.5 * M_PI;

if (angle > M_PI) {

           angle -= 2.0 * M_PI;

}

 

if (angle < 0.0) {

           *cos = 1.27323954 * angle +0.405284735 * angle * angle;

 

           if (*cos < 0.0) {

                    *cos = 0.225 * (*cos * -*cos- *cos) + *cos;

           } else {

                    *cos = 0.225 * (*cos * *cos- *cos) + *cos;

           }

} else {

           *cos = 1.27323954 * angle -0.405284735 * angle * angle;

 

           if (*cos < 0.0) {

                    *cos = 0.225 * (*cos * -*cos- *cos) + *cos;

           } else {

                    *cos = 0.225 * (*cos * *cos- *cos) + *cos;

           }

}

}

含有utils_fast_sincos_better(2.0f,&s,&c);代码大小

Program Size: Code=28100 RO-data=1012 RW-data=1608ZI-data=1560 

不含utils_fast_sincos_better(2.0f,&s,&c);代码大小

Program Size: Code=24768 RO-data=1016 RW-data=572ZI-data=1052 

utils_fast_sincos_better(2.0f,&s,&c);代码占:3332byte

执行时间:87us;执行结果:s = 0.9097958;c = -0.4157479

 

2、测试s = my_sin(2.0f);c = my_cos(2.0f);//匿名飞控

#define ONE_PI   (3.14159265)

#define TWO_PI   (2.0 * 3.14159265)

#define ANGLE_UNIT (TWO_PI/10.0)

double mx_sin(double rad)

{  

         doublesine;

         if(rad < 0)

                   sine= rad*(1.27323954f + 0.405284735f * rad);

         else

                   sine= rad * (1.27323954f - 0.405284735f * rad);

         if(sine < 0)

                   sine= sine*(-0.225f * (sine + 1) + 1);

         else

                   sine= sine * (0.225f *( sine - 1) + 1);

         returnsine;

}

 

double my_sin(double rad)

{

         s8flag = 1;

 

         if(rad >= ONE_PI)

         {

                   rad-= ONE_PI;

                   flag= -1;

         }

 

         returnmx_sin(rad) * flag;

}

 

float my_cos(double rad)

{

         s8flag = 1;

         rad+= ONE_PI/2.0;

 

         if(rad >= ONE_PI)

         {

                   flag= -1;

                   rad-= ONE_PI;

         }

 

         returnmy_sin(rad)*flag;

}

含有s = my_sin(2.0f);c =my_cos(2.0f);代码大小

Program Size:Code=28120 RO-data=1016 RW-data=1608 ZI-data=1560 

不含s = my_sin(2.0f);c =my_cos(2.0f); 代码大小

Program Size:Code=24768 RO-data=1016 RW-data=572 ZI-data=1052

s = my_sin(2.0f);c =my_cos(2.0f); 代码占:3352byte

执行时间:95us;执行结果:s = 0.9097958c = -0.4157479

 

3、测试s = sinf(2.0f);c = cosf(2.0f);//库函数带有

含有s = sinf(2.0f);c =cosf(2.0f);代码大小

Program Size: Code=26292 RO-data=1044 RW-data=572ZI-data=1052 

不含s = sinf(2.0f);c =cosf(2.0f); 代码大小

Program Size: Code=24768 RO-data=1016 RW-data=572ZI-data=1052

s = sinf(2.0f);c = cosf(2.0f);代码占:1524byte

执行时间:43us;执行结果:s = 0.9092974c = -0.4161468

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值