Functional Weave
Code in TypeScript

math.sin-cos@1.0.0

README.md

1,263 bytes · view raw

# math.sin-cos

Sine and cosine of an angle in radians, computed together with nothing but
`+`, `-`, `*` and `/`, so TypeScript, Python and Rust return the same doubles.
Used for arcs and pie slices, where a coordinate that lands on x.xx5 must round
the same way in every language. See `math.ln` for why the platform's `sin` and
`cos` cannot promise that.

## Method

1. Reduce: k = the nearest whole number of quarter turns, r = x - k pi/2, with
   pi/2 in two parts (fdlibm's `pio2_1`, 33 bits, and `pio2_1t`), so that
   k x pio2_1 is exact for every k the permitted range needs.
2. sin r and cos r by Taylor series to r^17 and r^18 on |r| <= pi/4, where they
   converge to well below an ulp.
3. Rotate by the quadrant k mod 4.

Results are within about 2e-16 of the true values. `sinCos(pi / 2).cos` is
6.1e-17, not 0, because pi/2 as a double is not exactly pi/2; every library
says the same. No `-0` is returned.

The angle must be within ±1,000,000 radians: beyond that the two-part pi/2 no
longer reduces exactly, and an angle that large is almost always a bug (degrees
passed as radians many times over).

Sources: W. J. Cody and W. Waite, *Software Manual for the Elementary
Functions* (1980); Sun Microsystems fdlibm, `e_rem_pio2.c` (the constants).