3

由于缺少 fp 操作单元,特定嵌入式系统上的 libmath 没有类似的功能sincos

是否有一些通过查找表提供功能的库?我实际上并不需要 100% 可靠的值。

4

5 回答 5

2

对于没有硬件浮点的目标,更好的方法可能是使用定点和 CORDIC 算法。

Anthony Williams 的定点数学库为标准数学库提供了一个完全类似的数据类型,该数据类型通常比同一目标上的软件浮点fixed快 5 倍左右。它是一个 C++ 库,但只要您的编译器支持 C++,即使您的其余代码不使用 C++ 特定功能,这也不成问题。在大多数情况下,移植代码以使用此库所需要做的就是将 math.h 替换为 fixed.hpp 并将 type 关键字和type替换。floatdoublefixed

于 2013-02-08T09:28:10.893 回答
2

根据所需的速度和精度要求,也许您可​​以通过编写程序来创建查找表来创建简单查找表所需的功能。或使用CORDIC

于 2013-02-08T07:48:27.237 回答
1

如果您的系统没有库为您提供 sin/cos 函数或内存中的查找表,您可以非常轻松地创建一个。

下一个 matlab 函数将sin(x)在 ac header 中为您提供([0,2*pi] range with 2*pi/100 step)myheader.h

step=2*pi/100;
x=[0:step:2*pi];
y=floor(0.5 * 65535 * sin(x));

fd=fopen('myheader.h','wt');
fprintf(fd,'int16_t y[%d]={%g',length(y),y(1));
fprintf(fd,',\n %.9g',y(2:end));
fprintf(fd,'};\n');
fclose(fd);

标题如下所示:

int16_t y[101]={0,
 2057,
 4107,
 6140,
 8149,
 10126,
 12063,
 13952,
 15786,
 17558,
 19260,
 20887,
 22431,
 23886,
 25248,
 26509,
 27667,
 28714,
 29649,
 30466,
 31164,
 31738,
 32187,
 32509,
 32703,
 32767,
 32703,
 32509,
 32187,
 31738,
 31164,
 30466,
 29649,
 28714,
 27667,
 26509,
 25248,
 23886,
 22431,
 20887,
 19260,
 17558,
 15786,
 13952,
 12063,
 10126,
 8149,
 6140,
 4107,
 2057,
 -0,
 -2057,
 -4107,
 -6140,
 -8149,
 -10126,
 -12063,
 -13952,
 -15786,
 -17558,
 -19260,
 -20887,
 -22431,
 -23886,
 -25248,
 -26509,
 -27667,
 -28714,
 -29649,
 -30466,
 -31164,
 -31738,
 -32187,
 -32509,
 -32703,
 -32768,
 -32703,
 -32509,
 -32187,
 -31738,
 -31164,
 -30466,
 -29649,
 -28714,
 -27667,
 -26509,
 -25248,
 -23886,
 -22431,
 -20887,
 -19260,
 -17558,
 -15786,
 -13952,
 -12063,
 -10126,
 -8149,
 -6140,
 -4107,
 -2057,
 -0};
于 2013-02-08T08:20:13.207 回答
0

我认为提供这样的库没有意义,因为与编写自己的库相比,设计选择和参数化太多了。我的意思是这些都不是很困难,但不能作为万能的解决方案提供。

  • 参数:

    • sin/cos == (unsigned) vs (signed) 的参数
    • 短,整数,浮点数,定点
    • 范围:有限(mod pi,mod 2pi)
    • 是自变量弧度、度数或其他值(例如 2pi==65536==0)
  • 价值

    • 浮点数 vs. 定点数 vs. 缩放整数
    • 仅第一象限,完整或扩展范围(无需模数减少参数)
    • 正弦和余弦,或者只是正弦
  • 要求

    • 代码大小
    • 数据大小
    • 执行速度
      • “恒定”对比
      • 允许有很多变化
    • 精确
      • 最小化一些最小二乘度量
      • 最小化一些最大误差
      • 最小化 1 - sin(x)^2 - cos(x)^2 误差
  • 方法

    • 直接 a=LUT[b]
    • 根据象限进行镜像:a=sign(b)*LUT[ b ^ mirror(b)]; // 概念公式
    • 科尔迪克
    • 三阶或五阶泰勒多项式
    • 使用两个 LUT 表增加(角度)精度 LUTA(x)=sin(x); LUTB(x)=sin(x/256) 和角度和的公式
于 2013-02-08T12:40:01.397 回答
0

Jack Ganssle 有一篇关于优化嵌入式系统触发的优秀文章:

http://www.ganssle.com/approx/approx.pdf

于 2013-02-08T12:00:28.583 回答