src/libm/s_sin.c
changeset 2756 a98604b691c8
child 3162 dc1eb82ffdaa
equal deleted inserted replaced
2755:2a3ec308d995 2756:a98604b691c8
       
     1 /* @(#)s_sin.c 5.1 93/09/24 */
       
     2 /*
       
     3  * ====================================================
       
     4  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
       
     5  *
       
     6  * Developed at SunPro, a Sun Microsystems, Inc. business.
       
     7  * Permission to use, copy, modify, and distribute this
       
     8  * software is freely granted, provided that this notice
       
     9  * is preserved.
       
    10  * ====================================================
       
    11  */
       
    12 
       
    13 #if defined(LIBM_SCCS) && !defined(lint)
       
    14 static char rcsid[] = "$NetBSD: s_sin.c,v 1.7 1995/05/10 20:48:15 jtc Exp $";
       
    15 #endif
       
    16 
       
    17 /* sin(x)
       
    18  * Return sine function of x.
       
    19  *
       
    20  * kernel function:
       
    21  *	__kernel_sin		... sine function on [-pi/4,pi/4]
       
    22  *	__kernel_cos		... cose function on [-pi/4,pi/4]
       
    23  *	__ieee754_rem_pio2	... argument reduction routine
       
    24  *
       
    25  * Method.
       
    26  *      Let S,C and T denote the sin, cos and tan respectively on
       
    27  *	[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
       
    28  *	in [-pi/4 , +pi/4], and let n = k mod 4.
       
    29  *	We have
       
    30  *
       
    31  *          n        sin(x)      cos(x)        tan(x)
       
    32  *     ----------------------------------------------------------
       
    33  *	    0	       S	   C		 T
       
    34  *	    1	       C	  -S		-1/T
       
    35  *	    2	      -S	  -C		 T
       
    36  *	    3	      -C	   S		-1/T
       
    37  *     ----------------------------------------------------------
       
    38  *
       
    39  * Special cases:
       
    40  *      Let trig be any of sin, cos, or tan.
       
    41  *      trig(+-INF)  is NaN, with signals;
       
    42  *      trig(NaN)    is that NaN;
       
    43  *
       
    44  * Accuracy:
       
    45  *	TRIG(x) returns trig(x) nearly rounded
       
    46  */
       
    47 
       
    48 #include "math.h"
       
    49 #include "math_private.h"
       
    50 
       
    51 libm_hidden_proto(sin)
       
    52 #ifdef __STDC__
       
    53      double sin(double x)
       
    54 #else
       
    55      double sin(x)
       
    56      double x;
       
    57 #endif
       
    58 {
       
    59     double y[2], z = 0.0;
       
    60     int32_t n, ix;
       
    61 
       
    62     /* High word of x. */
       
    63     GET_HIGH_WORD(ix, x);
       
    64 
       
    65     /* |x| ~< pi/4 */
       
    66     ix &= 0x7fffffff;
       
    67     if (ix <= 0x3fe921fb)
       
    68         return __kernel_sin(x, z, 0);
       
    69 
       
    70     /* sin(Inf or NaN) is NaN */
       
    71     else if (ix >= 0x7ff00000)
       
    72         return x - x;
       
    73 
       
    74     /* argument reduction needed */
       
    75     else {
       
    76         n = __ieee754_rem_pio2(x, y);
       
    77         switch (n & 3) {
       
    78         case 0:
       
    79             return __kernel_sin(y[0], y[1], 1);
       
    80         case 1:
       
    81             return __kernel_cos(y[0], y[1]);
       
    82         case 2:
       
    83             return -__kernel_sin(y[0], y[1], 1);
       
    84         default:
       
    85             return -__kernel_cos(y[0], y[1]);
       
    86         }
       
    87     }
       
    88 }
       
    89 
       
    90 libm_hidden_def(sin)