--
--	Inmos Libraries
--	Copyright (C) 1988, 1989, 1990, 1991, 1993  Inmos Limited
--
--	This library is free software; you can redistribute it and/or
--	modify it under the terms of the GNU Lesser General Public
--	License as published by the Free Software Foundation; either
--	version 2 of the License, or (at your option) any later version.
--
--	This library is distributed in the hope that it will be useful,
--	but WITHOUT ANY WARRANTY; without even the implied warranty of
--	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
--	Lesser General Public License for more details.
--
--	You should have received a copy of the GNU Lesser General Public
--	License along with this library; if not, write to the Free Software
--	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
--

--** @module maths

#IF NOT DEFINED(OCCBUILD.KROC)

#OPTION "V"  -- no vector space
#COMMENT "Floating point maths library, V1.1 27/03/90"
#COMMENT "(c) Copyright INMOS Limited 1988"
#INCLUDE "mathhdr.inc"

--* Double-precision cosine.
--
-- @param X Angle in radians
-- @return Cosine of X
REAL64 FUNCTION DCOS (VAL REAL64 X)

  --{{{  history
  -- V1.0 1-Jul-88
  -- Added OPTION "V"; V1.1 27-Mar-90 SRH
  --}}}

  REAL64 RWork :
  VALOF
    IF
      DNOTFINITE (X)
        --{{{  Inf or NaN
        IF
          DISNAN (X)
            RWork := X    -- transmit NaN
          TRUE
            RWork := Dundefined.NaN
        --}}}
      TRUE
        --{{{  definitions and variables
        -- Limit on X is Pi * 2**(ManBits/2). See C&W p134.
        -- XMax is 210828714.13315653800964355468750
        VAL REAL64 XMax RETYPES #41A921FB54442D18(INT64) :
        -- C1 + C2 = Pi to extra precision
        VAL REAL64 C1   RETYPES #4009220000000000(INT64) :
        VAL REAL64 C2   RETYPES #BEE2AEEF4B9EE59E(INT64) :
        REAL64 XWork :
        --}}}
        SEQ
          XWork := DABS (X)
          IF
            --{{{  special case
            XWork > XMax
              RWork := Dinexact.NaN
            --}}}
            TRUE
              INT32 N :
              SEQ
                --{{{  reduce argument
                N := INT32 ROUND ((X + DPiBy2) * DInvPi)
                VAL XN  IS (REAL64 ROUND N) - DHalf :
                XWork := (X - (XN * C1)) - (XN * C2) -- reduce argument
                --}}}
                --{{{  approximation in primary range
                IF
                  DABS(XWork) > Nearly.DPiBy2 -- cutoff to ensure result <= 1.0
                    IF
                      XWork > DZero
                        RWork := DOne
                      TRUE
                        RWork := - DOne
                  TRUE
                    -- XWork is in the range [-Nearly.DPiBy2, Nearly.DPiBy2]
                    -- This implementation uses a polynomial approximation from
                    -- Cody & Waite "Software Manual for the Elementary Functions"
                    -- pp125-138. The floating point version is used here.
                    --{{{  decimal coefficients
                    VAL R0 IS   2.7204790957888846175E-15(REAL64) :
                    VAL R1 IS  -7.6429178068910467734E-13(REAL64) :
                    VAL R2 IS   1.6058936490371589114E-10(REAL64) :
                    VAL R3 IS  -2.5052106798274584544E-8(REAL64) :
                    VAL R4 IS   2.7557319210152756119E-6(REAL64) :
                    VAL R5 IS  -1.9841269841201840457E-4(REAL64) :
                    VAL R6 IS   8.3333333333331650314E-3(REAL64) :
                    VAL R7 IS  -1.6666666666666665052E-1(REAL64) :
                    --}}}
                    VAL REAL64 G IS XWork * XWork :
                    RWork := ((((((((((((((((G*R0)+R1)*G)+R2)*G)+R3)*G)+R4)*G)+
                               R5)*G)+R6)*G)+R7)*G) * XWork) + XWork
                --}}}
                --{{{  set sign
                IF
                  ((N /\ one) = one)
                    RWork := - RWork
                  TRUE
                    SKIP
                --}}}
    RESULT RWork
:

#ENDIF
