Sine and cosine
This code from block 976 is loaded into node 610.
The input angle is an 18-bit fraction of a revolution; 1. is represented as 3ffff. One bit is 5 arcseconds. The cos is a 17-bit fraction, with 1. represented as 1ffff. This provides 5-digit accuracy.
*.
etherForth does not know ROM code, so the address of such code must be specified. *. does a signed multiply by a 17-bit fraction.
sin
Sin is computed by subtracting 90o from the input angle and falling into cos.
cos
The approximation used is taken from Computer Approximations by John F Hart, Wiley 1968; function 3300. This excellent reference has coefficients for many functions to various precisions. This approximation is
which is good to 17 bits between 0 and 90o.
- The input angle is an 18-bit fraction
- The simple function tri (triangle) is computed as a linear approximation. It ramps up and down as does the cos and establishes the sign of the result. As the angle counts from 0-3ffff
- tri starts at 1ffff
- counts down by 2s to 00001
- thence to -1, skipping 0
- counts down by 2s to 20001 (largest negative number +1)
- repeats 20001
- counts up by 2s to 1ffff (at angle 3ffff)
- The repetition at the peaks will, of course, occur with the cos. This is how you want 17-bit fractions to behave
- The effect is that a half-bit has been added to the input angle
- x is saved (dup) and squared
- x2 is multiplied by Hart's coefficients, scaled to 131,072
- Which is then multiplied by x
go
An infinite loop reading an angle from left (node 609) and returning sin and/or cos as desired.
Validation
I've plotted sin and cos which verifies gross behavior. I've displayed the residual of sin2 + cos2 - 1 which is a few bits from 0. And I've watched the bits near the peaks and zero crossings; all is as I expect.
I'm working on a 35-bit sin/cos which I'll use to check the 17-bit version.