amath  1.8.5
Simple command line calculator
tan.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_tan.c
30  *
31  *
32  * =================================================================
33  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
34  *
35  * Developed at SunSoft, a Sun Microsystems, Inc. business.
36  * Permission to use, copy, modify, and distribute this
37  * software is freely granted, provided that this notice
38  * is preserved.
39  * =================================================================
40  */
41 
42 /**
43  * @file tan.c
44  * @brief Tangent function
45  */
46 
47 #include "prim.h"
48 
49 /**
50  * @brief Tangent function
51  * @return Tangent 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 tan(double x)
88 {
89  double y[2], z = 0.0;
90  int32_t n, ix;
91 
92  GET_HIGH_WORD(ix, x);
93  ix &= 0x7FFFFFFF;
94 
95  // |x| ~< pi/4
96  if (ix <= 0x3FE921FB)
97  {
98  return __kernel_tan(x, z, 1);
99  }
100 
101  // tan(Inf or NaN) is NaN
102  if (ix >= 0x7FF00000)
103  {
104  return NAN;
105  }
106 
107  // |x| ~< pi/4
108  n = rempio2(x, y);
109  return __kernel_tan(y[0], y[1], 1 - ((n & 1) << 1));
110 }
double tan(double x)
Tangent function.
Definition: tan.c:87
#define GET_HIGH_WORD(i, d)
Get the more significant 32 bit int from a double.
Definition: prim.h:167
#define NAN
Definition: mathr.h:53
double __kernel_tan(double x, double y, int iy)
Kernel tan function.
Definition: ktan.c:108
int32_t rempio2(double x, double *y)
Definition: remp2.c:104