amath  1.8.5
Simple command line calculator
sin.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * Project homepage:
26  * https://amath.innolan.net
27  *
28  * The original source code can be obtained from:
29  * http://www.netlib.org/fdlibm/s_sin.c
30  *
31  * =================================================================
32  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
33  *
34  * Developed at SunSoft, a Sun Microsystems, Inc. business.
35  * Permission to use, copy, modify, and distribute this
36  * software is freely granted, provided that this notice
37  * is preserved.
38  * =================================================================
39  */
40 
41 /**
42  * @file sin.c
43  * @brief Sine function
44  */
45 
46 #include "prim.h"
47 
48 /**
49  * @brief Sine function
50  * @return Sine function of x
51  * @details
52  * <pre>
53  * Kernel function:
54  *
55  * __kernel_sin ... sine function on [-pi/4,pi/4]
56  * __kernel_cos ... cose function on [-pi/4,pi/4]
57  * __ieee754_rem_pio2 ... argument reduction routine
58  *
59  * Method:
60  *
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  *
65  * We have
66  *
67  * n sin(x) cos(x) tan(x)
68  * ----------------------------------------------------------
69  * 0 S C T
70  * 1 C -S -1/T
71  * 2 -S -C T
72  * 3 -C S -1/T
73  * ----------------------------------------------------------
74  *
75  * Special cases:
76  *
77  * Let trig be any of sin, cos, or tan.
78  * trig(+-INF) is NaN
79  * trig(NaN) is that NaN
80  *
81  * Accuracy:
82  *
83  * TRIG(x) returns trig(x) nearly rounded
84  * </pre>
85  */
86 double sin(double x)
87 {
88  double y[2], z = 0.0;
89  int32_t n, ix;
90 
91  GET_HIGH_WORD(ix, x);
92  ix &= 0x7FFFFFFF;
93 
94  // |x| ~< pi/4
95  if (ix <= 0x3FE921FB)
96  {
97  return __kernel_sin(x, z, 0);
98  }
99 
100  // sin(Inf or NaN) is NaN
101  if (ix >= 0x7FF00000)
102  {
103  return NAN;
104  }
105 
106  // argument reduction needed
107  n = rempio2(x, y);
108  switch (n & 3)
109  {
110  case 0:
111  return __kernel_sin(y[0], y[1], 1);
112  case 1:
113  return __kernel_cos(y[0], y[1]);
114  case 2:
115  return -__kernel_sin(y[0], y[1], 1);
116  default:
117  return -__kernel_cos(y[0], y[1]);
118  }
119 }
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
double __kernel_cos(double x, double y)
Kernel cosine function.
Definition: kcos.c:94
double __kernel_sin(double x, double y, int iy)
Kernel sin function.
Definition: ksin.c:89
#define NAN
Definition: mathr.h:53
double sin(double x)
Sine function.
Definition: sin.c:86
int32_t rempio2(double x, double *y)
Definition: remp2.c:104