--
--	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 sine.
--
-- @param X Angle in radians
-- @return Sine of X
REAL32 FUNCTION SIN (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
        INT32 N :
        REAL32 XWork :
        IF
          ABS(X) > SMax
            RWork := inexact.NaN
          TRUE
            SEQ
              --{{{  reduce argument
              N := INT32 ROUND (X * InvPi)
              XWork := REAL32 ROUND ((REAL64 X) - ((REAL64 ROUND N) * DPi))
              --}}}
              --{{{  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
                (N /\ one) = one
                  RWork := - RWork
                TRUE
                  SKIP
              --}}}
    RESULT RWork
:

#ENDIF
