1
2 /* @(#)s_sin.c 5.1 93/09/24 */
3 /*
4 * ====================================================
5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 *
7 * Developed at SunPro, 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 /*
15 FUNCTION
16 <<sin>>, <<sinf>>, <<cos>>, <<cosf>>---sine or cosine
17 INDEX
18 sin
19 INDEX
20 sinf
21 INDEX
22 cos
23 INDEX
24 cosf
25 SYNOPSIS
26 #include <math.h>
27 double sin(double <[x]>);
28 float sinf(float <[x]>);
29 double cos(double <[x]>);
30 float cosf(float <[x]>);
31
32 DESCRIPTION
33 <<sin>> and <<cos>> compute (respectively) the sine and cosine
34 of the argument <[x]>. Angles are specified in radians.
35
36 <<sinf>> and <<cosf>> are identical, save that they take and
37 return <<float>> values.
38
39
40 RETURNS
41 The sine or cosine of <[x]> is returned.
42
43 PORTABILITY
44 <<sin>> and <<cos>> are ANSI C.
45 <<sinf>> and <<cosf>> are extensions.
46
47 QUICKREF
48 sin ansi pure
49 sinf - pure
50 */
51
52 /* sin(x)
53 * Return sine function of x.
54 *
55 * kernel function:
56 * __kernel_sin ... sine function on [-pi/4,pi/4]
57 * __kernel_cos ... cose function on [-pi/4,pi/4]
58 * __rem_pio2 ... argument reduction routine
59 *
60 * Method.
61 * Let S,C and T denote the sin, cos and tan respectively on
62 * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
63 * in [-pi/4 , +pi/4], and let n = k mod 4.
64 * We have
65 *
66 * n sin(x) cos(x) tan(x)
67 * ----------------------------------------------------------
68 * 0 S C T
69 * 1 C -S -1/T
70 * 2 -S -C T
71 * 3 -C S -1/T
72 * ----------------------------------------------------------
73 *
74 * Special cases:
75 * Let trig be any of sin, cos, or tan.
76 * trig(+-INF) is NaN, with signals;
77 * trig(NaN) is that NaN;
78 *
79 * Accuracy:
80 * TRIG(x) returns trig(x) nearly rounded
81 */
82
83 #include "fdlibm.h"
84
85 #ifdef _NEED_FLOAT64
86
87 __float64
sin64(__float64 x)88 sin64(__float64 x)
89 {
90 __float64 y[2], z = _F_64(0.0);
91 __int32_t n, ix;
92
93 /* High word of x. */
94 GET_HIGH_WORD(ix, x);
95
96 /* |x| ~< pi/4 */
97 ix &= 0x7fffffff;
98 if (ix <= 0x3fe921fb)
99 return __kernel_sin(x, z, 0);
100
101 /* sin(Inf or NaN) is NaN */
102 else if (ix >= 0x7ff00000)
103 return __math_invalid(x);
104
105 /* argument reduction needed */
106 else {
107 n = __rem_pio2(x, y);
108 switch (n & 3) {
109 case 0:
110 return __kernel_sin(y[0], y[1], 1);
111 case 1:
112 return __kernel_cos(y[0], y[1]);
113 case 2:
114 return -__kernel_sin(y[0], y[1], 1);
115 default:
116 return -__kernel_cos(y[0], y[1]);
117 }
118 }
119 }
120
121 #if defined(_HAVE_ALIAS_ATTRIBUTE)
122 #ifndef __clang__
123 #pragma GCC diagnostic ignored "-Wmissing-attributes"
124 #endif
125 __strong_reference(_NAME_64(sin), _NAME_64(_sin));
126 #endif
127
128 _MATH_ALIAS_d_d(sin)
129
130 #endif /* _NEED_FLOAT64 */
131