快速sincos算法,stm32测试

发布于:2025-06-25 ⋅ 阅读:(20) ⋅ 点赞:(0)
#include "main_task.h"
#include <math.h>

//Remez快速正弦算法
#define M_PI (3.1415926f)

// lolremez --float --degree 5 --range "1e-50:pi*pi"
// "(sin(sqrt(x))-sqrt(x))/(x*sqrt(x))" "1/(x*sqrt(x))"
// Estimated max error: 1.455468e-9
static inline float f1(float x)
{
  float u = 1.3528548e-10f;
  u = u * x + -2.4703144e-08f;
  u = u * x + 2.7532926e-06f;
  u = u * x + -0.00019840381f;
  u = u * x + 0.0083333179f;
  return u * x + -0.16666666f;
}
// lolremez --float --degree 5 --range "1e-50:pi*pi" "(cos(sqrt(x))-1)/x"
// "1/x"
// Estimated max error: 1.1846383e-8
static inline float f2(float x)
{
  float u = 1.7290616e-09f;
  u = u * x + -2.7093486e-07f;
  u = u * x + 2.4771643e-05f;
  u = u * x + -0.0013887906f;
  u = u * x + 0.041666519f;
  return u * x + -0.49999991f;
}
static inline float fast_sin(float x)
{
  // si = (int)(x / pi)
  int si = (int)(x * 0.31830988f);
  x = x - (float)si * M_PI;
  if (si & 1)
  {
    x = x > 0.0f ? x - M_PI : x + M_PI;
  }
  return x + x * x * x * f1(x * x);
}
static inline float fast_cos(float x)
{
  // si = (int)(x / pi)
  int si = (int)(x * 0.31830988f);
  x = x - (float)si * M_PI;
  if (si & 1)
  {
    x = x > 0.0f ? x - M_PI : x + M_PI;
  }
  return 1.0f + x * x * f2(x * x);
}
static inline void fast_sin_cos(float x, float *sin_x, float *cos_x)
{
  // si = (int)(x / pi)
  int si = (int)(x * 0.31830988f);
  x = x - (float)si * M_PI;
  if (si & 1)
  {
    x = x > 0.0f ? x - M_PI : x + M_PI;
  }
  *sin_x = x + x * x * x * f1(x * x);
  *cos_x = 1.0f + x * x * f2(x * x);
}
void main_task(void)
{
	/* 初始化完毕打印当前编译日期时间 */
	DBG("\n");
	DBG("************************************\n");
	DBG("[data:%s][time:%s]\n", __DATE__, __TIME__);
	DBG("************************************\n");
	
	float m = 0, n = 0;
	uint32_t tickstart = HAL_GetTick();

	for(int i = 0; i < 1000; i++)
	{
		m += sin(i);
		n += cos(i);
	}
	
	DBG("sum = %f\n", m+n);
	
	uint32_t tickend = HAL_GetTick();
	
	DBG("time = %d\n", tickend-tickstart);
	
	m = n = 0;
	tickstart = HAL_GetTick();

	for(int i = 0; i < 1000; i++)
	{
		m += fast_sin(i);
		n += fast_cos(i);
	}
	
	DBG("sum = %f\n", m+n);
	
	tickend = HAL_GetTick();
	
	DBG("time = %d\n", tickend-tickstart);
	
	while(1)
	{
	}
}
************************************
[data:Jun 24 2025][time:17:15:29]
************************************
sum = 0.962697
time = 442
sum = 0.962912
time = 98

测试硬件是 STM32L031,主频32MHz。

标准的三角函数需要442ms,Remez快速正弦算法要98ms。


网站公告

今日签到

点亮在社区的每一天
去签到