%mathpiper,def="TruncRadian"

/// low-level numerical calculations of elementary functions.
/// These are only called if InNumericMode() returns True

/* TruncRadian truncates the radian r so it is between 0 and 2*Pi.
 * It calculates r mod 2*Pi using the required precision.
 */
TruncRadian(_r) <--
[
  Local(twopi);
  // increase precision by the number of digits of r before decimal point; enough to evaluate Abs(r) with 1 digit of precision
  N([
    r:=Eval(r);
    twopi:=2*Internal'Pi();
    r:=r-FloorN(r/twopi)*twopi;
  ], BuiltinPrecisionGet() + IntLog(Ceil(Abs(N(Eval(r), 1))), 10));
  r;
];
HoldArgument("TruncRadian",r);

%/mathpiper



%mathpiper_docs,name="TruncRadian",categories="Programmer Functions;Numerical (Arbitrary Precision)"
*CMD TruncRadian --- remainder modulo $2*Pi$
*STD
*CALL
	TruncRadian(r)

*PARMS

{r} -- a number

*DESC

{TruncRadian} calculates $Modulo(r,2*Pi)$, returning a value between $0$
and $2*Pi$. This function is used in the trigonometry functions, just
before doing a numerical calculation using a Taylor series. It greatly
speeds up the calculation if the value passed is a large number.

The library uses the formula
$$TruncRadian(r) = r - Floor( r/(2*Pi) )*2*Pi$$,
where $r$ and $2*Pi$ are calculated with twice the precision used in the
environment to make sure there is no rounding error in the significant
digits.

*E.G.

In> 2*Internal'Pi()
Result: 6.283185307;
In> TruncRadian(6.28)
Result: 6.28;
In> TruncRadian(6.29)
Result: 0.0068146929;

*SEE Sin, Cos, Tan

%/mathpiper_docs