\ CORDIC Demo for Forth
\ Supports 16-bit sines and cosines for +/-90 degrees
\ Requires core extension wordset
\ Dependency on 2s complement arithetic, cell size greater than 15 bits
\ Number format (where cells have w+1 bits)
\ bit w-15: sign bits (all 0s or all 1s)
\ bit 14: integer
\ bits 13-0: fraction
\ Original by Noel Henson.
\ Refactored by Neal Bridges, Oct. 2006.
\ and further ANSIfied by John Rible, 2006Oct20
\ and finally ported to 4tH by Hans Bezemer 2009Apr30
[hex]
4000 constant one
ffff constant 16bits
[decimal]
15 constant #cordic
#cordic array cordic-table
:this cordic-table does> swap cells + ;
variable kk
: reciprocal ( x y -- 1/x ) drop one dup rot */ ;
: arshift ( n1 i -- n2 ) 0 ?do 2/ loop ;
: circle ( z x y -- x y )
rot >r 0 begin \ ds: x y i rs: z
>r \ ds: x y rs: z i
over r@ arshift \ ds: x y dx rs: z i
over r@ arshift \ ds: x y dx dy rs: z i
r> r@ swap dup >r \ ds: x y dx dy z i rs: z i
cordic-table @ \ ds: x y dx dy z dz rs: z i
swap 0< if \ ds: x y dx dy dz rs: z i
>r >r negate \ ds: x y -dx rs: z i dz dy
else
negate >r negate >r \ ds: x y dx rs: z i -dz -dy
then + swap r> + swap \ ds: x' y' rs: z i ~dz
r> r> swap r> + >r \ ds: x' y' i rs: z'
1+ #cordic over = until \ ds: x' y' i' rs: z'
r> drop drop ;
: fill-cordic ( x#cordic ... x0 )
#cordic 0 do i cordic-table ! loop ;
: init-vars ( x#cordic ... x0 -- )
fill-cordic 0 ( z) one ( x) 0 ( y) circle reciprocal kk ! ;
: sincos ( z -- x y ) kk @ ( x) 0 ( y) circle ;
: sin ( angle -- magnitude ) sincos nip 16bits and ;
: cos ( angle -- magnitude ) sincos drop 16bits and ;
: tan ( angle -- tangent ) sincos one rot */ 16bits and ;
: deg ( angle -- binangle ) one 90 */ ;
: deg10ths ( angle -- binangle ) one 900 */ ;
: .frac ( fraction_of_one -- )
10000 one */ s>d <# # # # # [char] . hold #s #> type space ;
[hex]
: use-rad ( -- ) 1 2 4 8 10 20 40 80 100 200 3ff 7f5 0fae 1dac 3244
init-vars ;
: use-deg ( -- ) 1 1 3 5 0a 14 29 51 0a3 146 28b 511 9fb 12e4 2000
init-vars ;
[decimal]
\ use-rad \ for radians angle*one/(pi/2)
use-deg \ for degrees angle*one/90
\ examples
45 dup . deg sin .frac
105 cr dup . deg10ths sin .frac \ sin for 10.5
30 cr dup . deg cos .frac
554 cr dup . deg10ths cos .frac \ cos for 55.4
30 cr dup . deg tan .frac
0 cr dup . deg dup sin .frac cos .frac
90 cr dup . deg dup sin .frac cos .frac
cr
|