amath  1.8.5
Simple command line calculator
cos.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_cos.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 cos.c
43  * @brief Cosine function
44  */
45 
46 #include "prim.h"
47 
48 /**
49  * @brief Cosine function
50  * @param x
51  * @return Cosine function of x
52  * @details
53  * <pre>
54  * Kernel function:
55  *
56  * __kernel_sin ... sine function on [-pi/4,pi/4]
57  * __kernel_cos ... cose function on [-pi/4,pi/4]
58  * __ieee754_rem_pio2 ... argument reduction routine
59  *
60  * Method:
61  *
62  * Let S,C and T denote the sin, cos and tan respectively on
63  * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
64  * in [-pi/4 , +pi/4], and let n = k mod 4.
65  *
66  * We have
67  *
68  * n sin(x) cos(x) tan(x)
69  * ----------------------------------------------------------
70  * 0 S C T
71  * 1 C -S -1/T
72  * 2 -S -C T
73  * 3 -C S -1/T
74  * ----------------------------------------------------------
75  *
76  * Special cases:
77  *
78  * Let trig be any of sin, cos, or tan.
79  * trig(+-INF) is NaN
80  * trig(NaN) is that NaN
81  *
82  * Accuracy:
83  *
84  * TRIG(x) returns trig(x) nearly rounded
85  * </pre>
86  */
87 double cos(double x)
88 {
89  double y[2], z = 0.0;
90  int32_t n, ix;
91 
92  // High word of x
93  GET_HIGH_WORD(ix, x);
94  ix &= 0x7FFFFFFF;
95 
96  // |x| ~< pi/4
97  if (ix <= 0x3FE921FB)
98  {
99  return __kernel_cos(x, z);
100  }
101 
102  // cos(Inf or NaN) is NaN
103  if (ix >= 0x7FF00000)
104  {
105  return NAN;
106  }
107 
108  // argument reduction needed
109  n = rempio2(x, y);
110  switch (n & 3)
111  {
112  case 0:
113  return __kernel_cos(y[0], y[1]);
114  case 1:
115  return -__kernel_sin(y[0], y[1], 1);
116  case 2:
117  return -__kernel_cos(y[0], y[1]);
118  default:
119  return __kernel_sin(y[0], y[1], 1);
120  }
121 }
double cos(double x)
Cosine function.
Definition: cos.c:87
#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
int32_t rempio2(double x, double *y)
Definition: remp2.c:104