Reputation: 1877
I must do some calculations that need to use trigonometric functions, and especially the atan
one. The code will run on an Atmega328p, and for efficiency sake, I can't use float
s: I'm using fixed point numbers. Thus, I can't use the standard atan
function.
I which to have a function which take a value in fixed point format s16_10 (signed, 16 bits width, point in 10th position), and returns a s16_6 format. The input will be between 0 and 1 (so 0 and 210), so the output, in degrees, will be between -45 and 45 (so -45 * 26 and 45 * 26).
Let's say that Y is the fixed point, s16_6 representation of y, the real angle of the arc, and x such as atan(x) = y
, and X the s16_10 representation of x. I start with approximating the atan
function, from (0,1) to (-45,45) with a 4th degrees polynomial, and found that we can use:
y ~= 8.11 * x^4 - 19.67 * x^3 - 0.93 * x^2 + 57.52 * x + 0.0096
Which leads to:
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
And here am I stuck... On the one hand, computing the X^4
will lead to a 0 for one fifth of the definition interval, and on the other and the 2n4n in {3, 2, 1} will often lead also to a zero value... How could I do ?
Upvotes: 4
Views: 2107
Reputation:
Some of the terms being truncated to zero is not necessarily a disaster; this doesn't substantially worsen your approximation. I simulated your fixed precision setup in Matlab by rounding each term of the polynomial to the nearest integer:
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);
It's true that on the first fifth of the interval [0,210] the terms q4, q3, q2 look rather choppy, and q4 is essentially absent.
But these effects of rounding are of about the same size as the theoretical error of approximation of atan
by your polynomial. Here is the plot where red is the difference (polynomial-atan) calculated without rounding to integers, and green is the difference (q4+q3+q2+q1+q0-atan):
As you can see, rounding does not make approximation much worse; in most cases it actually reduces the error by a happy accident.
I do notice that your polynomial systematically overestimates atan. When I fit a 4th degree polynomial to atan on [0,1] with Matlab, the coefficients are slightly different:
8.0927 -19.6568 -0.9257 57.5106 -0.0083
Even truncating these to two significant figures, as you did, I get a better approximation:
(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
This time the truncation to integers does worsen things. But it is to be expected that the outcome of a calculation where several intermediate results are rounded to integers will be off by +-2 or so. The theoretical accuracy of +-0.5, shown by this polynomial, cannot be realized with the given arithmetical tools.
Upvotes: 5