我必须做一些需要使用三角函数的计算,尤其是 atan 一个。代码将在 Atmega328p 上运行,为了效率起见,我不能使用 float s:我使用的是定点数。因此,我不能使用标准的 atan 函数。

我有一个函数,它采用定点格式 s16_10(有符号,16 位宽度,指向第 10 个位置)的值,并返回一个 s16_6 格式。输入将介于 0 和 1 之间(因此为 0 和 210),因此输出(以度为单位)将介于 -45 和 45 之间(因此为 -45 * 26 和 45 * 26)。

假设 Y 是不动点,y 的 s16_6 表示,弧的实角,以及 x 诸如 atan(x) = y ,X 是 x 的 s16_10 表示。我首先用 4 次多项式逼近 atan 函数,从 (0,1) 到 (-45,45),发现我们可以使用:

y ~= 8.11 * x^4 - 19.67 * x^3 - 0.93 * x^2 + 57.52 * x + 0.0096

这导致:
Y ~= (8.11 * X^4)/2^34 - (19.62* X^3)/2^24 - (0.93 * X^2)/2^14 + (57.52*X)/2^4 + 0.0069 * 2^6

我在这里卡住了......一方面,计算 X^4 将导致定义区间的五分之一为 0,另一方面,{3, 2, 1} 中的 2n4n 通常也会导致零值(value)...我该怎么办?

最佳答案

有些术语被截断为零不一定是灾难;这不会大大恶化您的近似值。我通过将多项式的每一项四舍五入到最接近的整数来模拟您在 Matlab 中的固定精度设置:

q4 = @(X) round((8.11 * X.^4)/2^34);
q3 = @(X) -round((19.62* X.^3)/2^24);
q2 = @(X) -round((0.93 * X.^2)/2^14);
q1 = @(X) round((57.52*X)/2^4);
q0 = @(X) round(0.0069 * 2^6);

确实,在区间 [0,210] 的前五分之一,项 q4、q3、q2 看起来相当不稳定,而 q4 基本上不存在。

但是这些舍入的影响与您的多项式近似 atan 的理论误差的大小大致相同。这是图中红色是计算的差值(多项式-atan),没有四舍五入到整数,绿色是差值(q4+q3+q2+q1+q0-atan):



如您所见,舍入不会使近似变得更糟;在大多数情况下,它实际上通过一个愉快的事故减少了错误。

我确实注意到您的多项式系统地高估了 atan。当我使用 Matlab 在 [0,1] 上将 4 次多项式拟合到 atan 时,系数略有不同:
8.0927  -19.6568   -0.9257   57.5106   -0.0083

即使像你一样将这些截断为两个有效数字,我也得到了一个更好的近似值:
(8.09 * X^4)/2^34 - (19.66* X^3)/2^24 - (0.93 * X^2)/2^14 + (57.52*X)/2^4 - 0.0083 * 2^6

这次截断为整数确实使事情变得更糟。但是可以预料,将几个中间结果四舍五入为整数的计算结果将偏离 +-2 左右。该多项式显示的 +-0.5 的理论精度无法使用给定的算术工具实现。

关于math - `atan` 函数在定点的逼近,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30243268/

10-15 00:35