I was looking for a better atan approximation and I have come up with the following three.

They all work in exactly the same way as the X2 builtin atan function:

- They provide an arctan function for angles between 0 and 45 degrees.
- The same coding system is used for the input value. The value is 100 x the real atan value (e.g. 0.39 = 39)
- e.g let b1 = atan 100 (answer b1 = 45)

To judge the accuracy of the approximations I'm comparing them with the spreadsheet funciton =round(atan(A/100)*180/pi()). The best approximation is one that gives the same result as this spreadsheet function for all 101 values of A from 0 to 100.

For measuring the error I'm comparing them with the spreadsheet funciton =atan(A/100)*180/pi(). Because we are rounding or truncating the result to an integer value the best possible absolute error is 0.5 degree and this is the maximum aboslute error for the spreadsheet funciton =round(atan(A/100)*180/pi()).

I used a 20X2 chip for all my tests.

Atan approximation #1

b0=input value

output value=364-b0*b0/580

- 7.25% faster than the builtin atan function
- Gives the same result as the spreadsheet function for 97 out of the 101 input values. The builtin atan function gives the same result for 74 out of 101 input values.
- Maximum abolute error is 0.72 degrees compared to 0.95 degrees for the builtin atan funciton.
- Only 12 bytes of code.
- Does not require any variables for intermediate results. If you don' t need to save the input value you can code the function as b0=364-b0*b0/580
- You can also define this approximation as a macro "#DEFINE atan(reg) 364-reg*reg/580" and then call it in your code in a similar fashion to the builtin function: b1=atan(b0)

Atan approximation #2

This one line implementation of the code is courtesy of Hippy in post #2 and replaces my original two lines of code.

b0=input value

output value=b0+250*b0/251^$FFFF+581*b0+400/979

- Half as fast as the builtin atan function.
- Gives the same result as the spreadsheet function for all 101 input values.
- Maximum absolute error is 0.5 degrees.
- 25 bytes of code.
- Does not require any variables for intermediate results. If you don' t need to save the input value you can code the fuction as b0=b0+250*b0/251^$FFFF+581*b0+400/979
- You can also define this approximation as a macro "#DEFINE atan(reg) reg+250*reg/251^$FFFF+581*reg+400/979" and then call it in your code in a similar fashion to the builtin function: b1=atan(b0)

If you #DEFINE the atan approximation as a macro then the rules for using that macro are the same as for using the builtin atan unary command:

let b1 = atan(30) + 5 ' Is valid

- It must be the first command on a program line.
- It may be followed by additional mathematical commands.

let b1 = 5 + atan(30) ' Is not valid. It won't generate a syntax error but it will return the wrong result.

Atan approximation #3

eeprom (0,1,1,2,2,3,3,4,5,5,6,6,7,7,8,9,9,10,10,11,11,12, 12,13,13,14,15,15,16,16,17,17,18,18,19,19,20,20,21 ,21,22,22,23,23,24,24,25,25,26,26,27,27,27,28,28,2 9,29,30,30,31,31,31,32,32,33,33,33,34,34,35,35,35, 36,36,37,37,37,38,38,38,39,39,39,40,40,40,41,41,41 ,42,42,42,43,43,43,44,44,44,44,45,45)

read b0, b1

- Four times as fast as the builtin atan function.
- Gives the same result as the spreadsheet function for all 101 input values.
- Maximum absolute error is 0.5 degrees.
- 3 bytes of code and 101 bytes of data.

The code to test the speed toggles a pin on a 20X2 that is running at 4MHz and the pulse width was measured using PULSEIN on an 08M2 that is running at 4MHz. The values for 100 pulses were averaged to get the final result for each test.

atan speed tests.jpg

Post updated 11/04/2015 - Added approximation #3

Post updated 06/04/2015 - Replaced these original two lines of code for approximation #2 with the one line of code provided by Hippy

b3=b0+250*b0/251

output value=580-b3*b0+400/979

## Bookmarks