uc-sdk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
s_sin.c
Go to the documentation of this file.
1 
2 /* @(#)s_sin.c 1.3 95/01/18 */
3 /*
4  * ====================================================
5  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6  *
7  * Developed at SunSoft, a Sun Microsystems, Inc. business.
8  * Permission to use, copy, modify, and distribute this
9  * software is freely granted, provided that this notice
10  * is preserved.
11  * ====================================================
12  */
13 
14 /* sin(x)
15  * Return sine function of x.
16  *
17  * kernel function:
18  * __kernel_sin ... sine function on [-pi/4,pi/4]
19  * __kernel_cos ... cose function on [-pi/4,pi/4]
20  * __ieee754_rem_pio2 ... argument reduction routine
21  *
22  * Method.
23  * Let S,C and T denote the sin, cos and tan respectively on
24  * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
25  * in [-pi/4 , +pi/4], and let n = k mod 4.
26  * We have
27  *
28  * n sin(x) cos(x) tan(x)
29  * ----------------------------------------------------------
30  * 0 S C T
31  * 1 C -S -1/T
32  * 2 -S -C T
33  * 3 -C S -1/T
34  * ----------------------------------------------------------
35  *
36  * Special cases:
37  * Let trig be any of sin, cos, or tan.
38  * trig(+-INF) is NaN, with signals;
39  * trig(NaN) is that NaN;
40  *
41  * Accuracy:
42  * TRIG(x) returns trig(x) nearly rounded
43  */
44 
45 #include "fdlibm.h"
46 
47 #ifdef __STDC__
48  double sin(double x)
49 #else
50  double sin(x)
51  double x;
52 #endif
53 {
54  double y[2],z=0.0;
55  int n, ix;
56 
57  /* High word of x. */
58  ix = __HI(x);
59 
60  /* |x| ~< pi/4 */
61  ix &= 0x7fffffff;
62  if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
63 
64  /* sin(Inf or NaN) is NaN */
65  else if (ix>=0x7ff00000) return x-x;
66 
67  /* argument reduction needed */
68  else {
69  n = __ieee754_rem_pio2(x,y);
70  switch(n&3) {
71  case 0: return __kernel_sin(y[0],y[1],1);
72  case 1: return __kernel_cos(y[0],y[1]);
73  case 2: return -__kernel_sin(y[0],y[1],1);
74  default:
75  return -__kernel_cos(y[0],y[1]);
76  }
77  }
78 }