--
--	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"

--* Single-precision cosine.
--
-- @param X Angle in radians
-- @return Cosine of X
REAL32 FUNCTION COS (VAL REAL32 X)

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

  REAL32 RWork :
  VALOF
    IF
      NOTFINITE (X)
        --{{{  NaN or Inf
        IF
          ISNAN (X)
            RWork := X    -- transmit NaN
          TRUE
            RWork := undefined.NaN
        --}}}
      TRUE
        REAL32 XWork :
        SEQ
          XWork := ABS (X)
          IF
            --{{{  too large
            XWork > SMax
              RWork := inexact.NaN
            --}}}
            TRUE
              BOOL Odd :
              SEQ
                --{{{  reduce argument
                VAL REAL64 DInvPi RETYPES #3FD45F306DC9C883(INT64) : -- 1/Pi
                VAL two IS 2(INT32) :
                INT32 N :
                SEQ
                  N := INT32 ROUND (((REAL64 XWork) + DPiBy2) * DInvPi)
                  XWork := REAL32 ROUND ((REAL64 XWork) -
                           (DDIVBY2 (REAL64 ROUND ((N TIMES two) - one)) * DPi))
                  Odd := ((N /\ one) = one)
                --}}}
                --{{{  approximation in primary range
                IF
                  ABS(XWork) > Nearly.PiBy2 -- trap to ensure |result| <= 1
                    IF
                      XWork < Zero
                        RWork := - One
                      TRUE
                        RWork := One
                  TRUE
                    -- XWork is in the range [-Nearly.PiBy2, Nearly.PiBy2]
                    -- This implementation uses a polynomial approximation from
                    -- Cody & Waite "Software Manual for the Elementary Functions",
                    -- pp125-138. The floating point version is used here.
                    VAL R IS [2.601903036E-6(REAL32), -1.980741872E-4(REAL32),
                              8.333025139E-3(REAL32), -1.666665668E-1(REAL32)] :
                    VAL REAL32 G IS XWork * XWork :
                    RWork := ((((((((R[0]*G)+R[1])*G)+R[2])*G)+R[3])*G)*XWork)+XWork
                --}}}
                --{{{  set sign
                IF
                  Odd
                    RWork := - RWork
                  TRUE
                    SKIP
                --}}}
    RESULT RWork
:

#ENDIF
