"atan"函数在不动点的逼近

Spi*_*ine 4 math microcontroller atmega trigonometry approximation

我必须做一些需要使用三角函数的计算,特别是那个atan.代码将在Atmega328p上运行,为了提高效率,我不能使用floats:我使用的是定点数.因此,我无法使用标准atan功能.

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

假设Y是固定点,y是s16_6表示,弧的实际角度,x是x atan(x) = y,X是s16_10的x表示.我从使用atan4度多项式近似函数,从(0,1)到(-45,45)开始,发现我们可以使用:

y ~= 8.11 * x^4 - 19.67 * x^3 - 0.93 * x^2 + 57.52 * x + 0.0096
Run Code Online (Sandbox Code Playgroud)

这导致:

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
Run Code Online (Sandbox Code Playgroud)

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

小智 5

一些被截断为零的术语不一定是灾难; 这并没有大大恶化你的近似值.我通过将多项式的每个项四舍五入到最接近的整数来模拟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);
Run Code Online (Sandbox Code Playgroud)

这是真的,在区间[0,2的第五首10 ]的条款Q4,Q3,Q2看起来相当波涛汹涌,和Q4是基本上不存在.

条款

但这些舍入的影响大小与atan你的多项式逼近的理论误差大致相同.下面的图是红色是差异(多项式 - atan)计算而没有舍入到整数,绿色是差异(q4 + q3 + q2 + q1 + q0-atan):

atanapprox

正如您所看到的,舍入不会使逼近变得更糟; 在大多数情况下,它实际上通过一次快乐事故减少了错误.


我注意到你的多项式系统地过高估计了atan.当我用Matlab将4次多项式拟合到[0,1]上时,系数略有不同:

8.0927  -19.6568   -0.9257   57.5106   -0.0083
Run Code Online (Sandbox Code Playgroud)

即使将这些截断为两位有效数字,我也会得到更好的近似值:

(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
Run Code Online (Sandbox Code Playgroud)

betterpoly

这一次截断到整数会使事情恶化.但是可以预期,将几个中间结果四舍五入为整数的计算结果将偏离+ -2左右.用这个多项式表示的+ -0.5的理论精度不能用给定的算术工具来实现.