From Newsgroup: comp.lang.forth
On 8/15/26 07:32, Krishna Myneni wrote:
A simple Forth implementation for reducing large angles (|x| > 500000
rad) for accurate evaluation by the x87 native fpu trig instructions
FSIN FCOS FSINCOS FTAN is given below. The Forth code relies on the
Forth Scientific Library (FSL #47) big number arithmetic module.
...
=== begin rr-big.4th ===
\ rr-big.4th
\
\ Perform range reduction of large angle x (radians) for
\ accurate trigonometric functions with x87 using the FSL
\ big number arithmetic module.
\
\ K. Myneni, 2026-08-15
\
\ Notes:
\ 1. Angles |x| < DP_RR_CUTOFF are not reduced. The
\-a-a-a-a-a native x87 trig functions are accurate.
\
\ 2. Range reduction is valid over the range,
\-a-a-a |x| < DP_RR_MAX_ANGLE
\
include ans-words
include modules
include ieee-754
include fsl/big
include fsl/extras/big-extras
8 constant BIG_DBL
5.0e05 fconstant-a-a DP_RR_CUTOFF
9.2e18 fconstant-a-a DP_RR_MAX_ANGLE
\ BIG number constants and variables
create-a 5^52-a-a-a BIG_DBL CELLS allot-a-a 5 52 big_s^n-a 5^52 big-move create 10^52-a-a-a BIG_DBL CELLS allot-a 10 52 big_s^n 10^52 big-move
create BIG_2PI-a BIG_DBL CELLS allot
big 62831853071795864769252867665590057683943387987502116
BIG_2PI big-move
: exponent ( F: r -- ) ( -- n ) fexponent 1023 - ;
variable m
: freduce-range ( F: r1 -- r2)
-a-a-a \ Store sign, perform error checks
-a-a-a fdup f0< >r-a ( R: bsign)
-a-a-a fabs
-a-a-a fdup DP_RR_CUTOFF f< IF
-a-a-a-a-a r> IF fnegate THEN EXIT-a \ no rr correction
-a-a-a THEN
-a-a-a fdup DP_RR_MAX_ANGLE f> IF-a \ exceed limit of algorithm
-a-a-a-a-a cr ." Angle out of range." cr
-a-a-a-a-a -46 throw
-a-a-a THEN
-a-a-a fdup PI 2e f* f/ ftrunc>s m ! \ multiple of 2pi
-a-a-a \ Perform range reduction
-a-a-a fdup ffraction drop >r big-here dup 5^52 big>here
-a-a-a r> big*s 10^52 big+ >r-a ( R: abig bsign) ( F: r)
-a-a-a exponent 1 swap lshift
-a-a-a r@ swap big*s
-a-a-a r> r> IF bignegate THEN
-a-a-a big-here dup BIG_2PI big>here m @ big*s
-a-a-a big-
-a-a-a dup big0< swap dup bigabs <big# big#s swap bigsign #big>
-a-a-a >float IF
-a-a-a-a-a-a 1.0e-52 f*
-a-a-a ELSE
-a-a-a-a-a ." Conversion to double-precision float error!"
-a-a-a-a-a 0e
-a-a-a THEN
;
=== end rr-big.4th ===
I forgot to mention that the code above assumes a 64-bit Forth system
with a separate fp stack.
--
KM
--- Synchronet 3.22a-Linux NewsLink 1.2