Little fix after the last commit (mostly a git fail)
[eigenmath-fx.git] / tan.cpp
blob0682b9ed6137a311e26afcdd6f84ce900a0a8a5d
1 // Tangent function of numerical and symbolic arguments
3 #include "stdafx.h"
4 #include "defs.h"
6 void
7 eval_tan(void)
9 push(cadr(p1));
10 eval();
11 tangent();
14 void
15 tangent(void)
17 save();
18 yytangent();
19 restore();
22 void
23 yytangent(void)
25 int n;
26 double d;
28 p1 = pop();
30 if (car(p1) == symbol(ARCTAN)) {
31 push(cadr(p1));
32 return;
35 if (isdouble(p1)) {
36 d = tan(p1->u.d);
37 if (fabs(d) < 1e-10)
38 d = 0.0;
39 push_double(d);
40 return;
43 // tan function is antisymmetric, tan(-x) = -tan(x)
45 if (isnegative(p1)) {
46 push(p1);
47 negate();
48 tangent();
49 negate();
50 return;
53 // multiply by 180/pi
55 push(p1);
56 push_integer(180);
57 multiply();
58 push_symbol(PI);
59 divide();
61 n = pop_integer();
63 if (n < 0) {
64 push(symbol(TAN));
65 push(p1);
66 list(2);
67 return;
70 switch (n % 360) {
71 case 0:
72 case 180:
73 push_integer(0);
74 break;
75 case 30:
76 case 210:
77 push_rational(1, 3);
78 push_integer(3);
79 push_rational(1, 2);
80 power();
81 multiply();
82 break;
83 case 150:
84 case 330:
85 push_rational(-1, 3);
86 push_integer(3);
87 push_rational(1, 2);
88 power();
89 multiply();
90 break;
91 case 45:
92 case 225:
93 push_integer(1);
94 break;
95 case 135:
96 case 315:
97 push_integer(-1);
98 break;
99 case 60:
100 case 240:
101 push_integer(3);
102 push_rational(1, 2);
103 power();
104 break;
105 case 120:
106 case 300:
107 push_integer(3);
108 push_rational(1, 2);
109 power();
110 negate();
111 break;
112 default:
113 push(symbol(TAN));
114 push(p1);
115 list(2);
116 break;
120 #if SELFTEST
122 static char *s[] = {
124 "tan(x)",
125 "tan(x)",
127 "tan(-x)",
128 "-tan(x)",
130 "tan(b-a)",
131 "-tan(a-b)",
133 // check against the floating point math library
135 "f(a,x)=1+tan(float(a/360*2*pi))-float(x)+tan(a/360*2*pi)-x",
138 "f(0,0)", // 0
139 "1",
141 "f(180,0)", // 180
142 "1",
144 "f(360,0)", // 360
145 "1",
147 "f(-180,0)", // -180
148 "1",
150 "f(-360,0)", // -360
151 "1",
153 "f(45,1)", // 45
154 "1",
156 "f(135,-1)", // 135
157 "1",
159 "f(225,1)", // 225
160 "1",
162 "f(315,-1)", // 315
163 "1",
165 "f(-45,-1)", // -45
166 "1",
168 "f(-135,1)", // -135
169 "1",
171 "f(-225,-1)", // -225
172 "1",
174 "f(-315,1)", // -315
175 "1",
177 "f(30,sqrt(3)/3)", // 30
178 "1",
180 "f(150,-sqrt(3)/3)", // 150
181 "1",
183 "f(210,sqrt(3)/3)", // 210
184 "1",
186 "f(330,-sqrt(3)/3)", // 330
187 "1",
189 "f(-30,-sqrt(3)/3)", // -30
190 "1",
192 "f(-150,sqrt(3)/3)", // -150
193 "1",
195 "f(-210,-sqrt(3)/3)", // -210
196 "1",
198 "f(-330,sqrt(3)/3)", // -330
199 "1",
201 "f(60,sqrt(3))", // 60
202 "1",
204 "f(120,-sqrt(3))", // 120
205 "1",
207 "f(240,sqrt(3))", // 240
208 "1",
210 "f(300,-sqrt(3))", // 300
211 "1",
213 "f(-60,-sqrt(3))", // -60
214 "1",
216 "f(-120,sqrt(3))", // -120
217 "1",
219 "f(-240,-sqrt(3))", // -240
220 "1",
222 "f(-300,sqrt(3))", // -300
223 "1",
225 "f=quote(f)",
228 "tan(arctan(x))",
229 "x",
231 // check the default case
233 "tan(1/12*pi)",
234 "tan(1/12*pi)",
237 void
238 test_tan(void)
240 test(__FILE__, s, sizeof s / sizeof (char *));
243 #endif