1 /*
2  * IBM Accurate Mathematical Library
3  * written by International Business Machines Corp.
4  * Copyright (C) 2001-2022 Free Software Foundation, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, see <https://www.gnu.org/licenses/>.
18  */
19 /*********************************************************************/
20 /*  MODULE_NAME: utan.c                                              */
21 /*                                                                   */
22 /*  FUNCTIONS: utan                                                  */
23 /*                                                                   */
24 /*  FILES NEEDED:dla.h endian.h mydefs.h utan.h                      */
25 /*               branred.c                                           */
26 /*               utan.tbl                                            */
27 /*                                                                   */
28 /*********************************************************************/
29 
30 #include <errno.h>
31 #include <float.h>
32 #include "endian.h"
33 #include <dla.h>
34 #include "mydefs.h"
35 #include <math.h>
36 #include <math_private.h>
37 #include <fenv_private.h>
38 #include <math-underflow.h>
39 #include <libm-alias-double.h>
40 #include <fenv.h>
41 
42 #ifndef SECTION
43 # define SECTION
44 #endif
45 
46 /* tan with max ULP of ~0.619 based on random sampling.  */
47 double
48 SECTION
__tan(double x)49 __tan (double x)
50 {
51 #include "utan.h"
52 #include "utan.tbl"
53 
54   int ux, i, n;
55   double a, da, a2, b, db, c, dc, fi, gi, pz,
56 	 s, sy, t, t1, t2, t3, t4, w, x2, xn, y, ya,
57          yya, z0, z, z2;
58   mynumber num, v;
59 
60   double retval;
61 
62   int __branred (double, double *, double *);
63 
64   SET_RESTORE_ROUND_53BIT (FE_TONEAREST);
65 
66   /* x=+-INF, x=NaN */
67   num.d = x;
68   ux = num.i[HIGH_HALF];
69   if ((ux & 0x7ff00000) == 0x7ff00000)
70     {
71       if ((ux & 0x7fffffff) == 0x7ff00000)
72 	__set_errno (EDOM);
73       retval = x - x;
74       goto ret;
75     }
76 
77   w = (x < 0.0) ? -x : x;
78 
79   /* (I) The case abs(x) <= 1.259e-8 */
80   if (w <= g1.d)
81     {
82       math_check_force_underflow_nonneg (w);
83       retval = x;
84       goto ret;
85     }
86 
87   /* (II) The case 1.259e-8 < abs(x) <= 0.0608 */
88   if (w <= g2.d)
89     {
90       x2 = x * x;
91 
92       t2 = d9.d + x2 * d11.d;
93       t2 = d7.d + x2 * t2;
94       t2 = d5.d + x2 * t2;
95       t2 = d3.d + x2 * t2;
96       t2 *= x * x2;
97 
98       y = x + t2;
99       retval = y;
100       /* Max ULP is 0.504.  */
101       goto ret;
102     }
103 
104   /* (III) The case 0.0608 < abs(x) <= 0.787 */
105   if (w <= g3.d)
106     {
107       i = ((int) (mfftnhf.d + 256 * w));
108       z = w - xfg[i][0].d;
109       z2 = z * z;
110       s = (x < 0.0) ? -1 : 1;
111       pz = z + z * z2 * (e0.d + z2 * e1.d);
112       fi = xfg[i][1].d;
113       gi = xfg[i][2].d;
114       t2 = pz * (gi + fi) / (gi - pz);
115       y = fi + t2;
116       retval = (s * y);
117       /* Max ULP is 0.60.  */
118       goto ret;
119     }
120 
121   /* (---) The case 0.787 < abs(x) <= 25 */
122   if (w <= g4.d)
123     {
124       /* Range reduction by algorithm i */
125       t = (x * hpinv.d + toint.d);
126       xn = t - toint.d;
127       v.d = t;
128       t1 = (x - xn * mp1.d) - xn * mp2.d;
129       n = v.i[LOW_HALF] & 0x00000001;
130       da = xn * mp3.d;
131       a = t1 - da;
132       da = (t1 - a) - da;
133       if (a < 0.0)
134 	{
135 	  ya = -a;
136 	  yya = -da;
137 	  sy = -1;
138 	}
139       else
140 	{
141 	  ya = a;
142 	  yya = da;
143 	  sy = 1;
144 	}
145 
146       /* (VI) The case 0.787 < abs(x) <= 25,    0 < abs(y) <= 0.0608 */
147       if (ya <= gy2.d)
148 	{
149 	  a2 = a * a;
150 	  t2 = d9.d + a2 * d11.d;
151 	  t2 = d7.d + a2 * t2;
152 	  t2 = d5.d + a2 * t2;
153 	  t2 = d3.d + a2 * t2;
154 	  t2 = da + a * a2 * t2;
155 
156 	  if (n)
157 	    {
158 	      /* -cot */
159 	      EADD (a, t2, b, db);
160 	      DIV2 (1.0, 0.0, b, db, c, dc, t1, t2, t3, t4);
161 	      y = c + dc;
162 	      retval = (-y);
163 	      /* Max ULP is 0.506.  */
164 	      goto ret;
165 	    }
166 	  else
167 	    {
168 	      /* tan */
169 	      y = a + t2;
170 	      retval = y;
171 	      /* Max ULP is 0.506.  */
172 	      goto ret;
173 	    }
174 	}
175 
176       /* (VII) The case 0.787 < abs(x) <= 25,    0.0608 < abs(y) <= 0.787 */
177 
178       i = ((int) (mfftnhf.d + 256 * ya));
179       z = (z0 = (ya - xfg[i][0].d)) + yya;
180       z2 = z * z;
181       pz = z + z * z2 * (e0.d + z2 * e1.d);
182       fi = xfg[i][1].d;
183       gi = xfg[i][2].d;
184 
185       if (n)
186 	{
187 	  /* -cot */
188 	  t2 = pz * (fi + gi) / (fi + pz);
189 	  y = gi - t2;
190 	  retval = (-sy * y);
191 	  /* Max ULP is 0.62.  */
192 	  goto ret;
193 	}
194       else
195 	{
196 	  /* tan */
197 	  t2 = pz * (gi + fi) / (gi - pz);
198 	  y = fi + t2;
199 	  retval = (sy * y);
200 	  /* Max ULP is 0.62.  */
201 	  goto ret;
202 	}
203     }
204 
205   /* (---) The case 25 < abs(x) <= 1e8 */
206   if (w <= g5.d)
207     {
208       /* Range reduction by algorithm ii */
209       t = (x * hpinv.d + toint.d);
210       xn = t - toint.d;
211       v.d = t;
212       t1 = (x - xn * mp1.d) - xn * mp2.d;
213       n = v.i[LOW_HALF] & 0x00000001;
214       da = xn * pp3.d;
215       t = t1 - da;
216       da = (t1 - t) - da;
217       t1 = xn * pp4.d;
218       a = t - t1;
219       da = ((t - a) - t1) + da;
220       EADD (a, da, t1, t2);
221       a = t1;
222       da = t2;
223       if (a < 0.0)
224 	{
225 	  ya = -a;
226 	  yya = -da;
227 	  sy = -1;
228 	}
229       else
230 	{
231 	  ya = a;
232 	  yya = da;
233 	  sy = 1;
234 	}
235 
236       /* (VIII) The case 25 < abs(x) <= 1e8,    0 < abs(y) <= 0.0608 */
237       if (ya <= gy2.d)
238 	{
239 	  a2 = a * a;
240 	  t2 = d9.d + a2 * d11.d;
241 	  t2 = d7.d + a2 * t2;
242 	  t2 = d5.d + a2 * t2;
243 	  t2 = d3.d + a2 * t2;
244 	  t2 = da + a * a2 * t2;
245 
246 	  if (n)
247 	    {
248 	      /* -cot */
249 	      EADD (a, t2, b, db);
250 	      DIV2 (1.0, 0.0, b, db, c, dc, t1, t2, t3, t4);
251 	      y = c + dc;
252 	      retval = (-y);
253 	      /* Max ULP is 0.506.  */
254 	      goto ret;
255 	    }
256 	  else
257 	    {
258 	      /* tan */
259 	      y = a + t2;
260 	      retval = y;
261 	      /* Max ULP is 0.506.  */
262 	      goto ret;
263 	    }
264 	}
265 
266       /* (IX) The case 25 < abs(x) <= 1e8,    0.0608 < abs(y) <= 0.787 */
267       i = ((int) (mfftnhf.d + 256 * ya));
268       z = (z0 = (ya - xfg[i][0].d)) + yya;
269       z2 = z * z;
270       pz = z + z * z2 * (e0.d + z2 * e1.d);
271       fi = xfg[i][1].d;
272       gi = xfg[i][2].d;
273 
274       if (n)
275 	{
276 	  /* -cot */
277 	  t2 = pz * (fi + gi) / (fi + pz);
278 	  y = gi - t2;
279 	  retval = (-sy * y);
280 	  /* Max ULP is 0.62.  */
281 	  goto ret;
282 	}
283       else
284 	{
285 	  /* tan */
286 	  t2 = pz * (gi + fi) / (gi - pz);
287 	  y = fi + t2;
288 	  retval = (sy * y);
289 	  /* Max ULP is 0.62.  */
290 	  goto ret;
291 	}
292     }
293 
294   /* (---) The case 1e8 < abs(x) < 2**1024 */
295   /* Range reduction by algorithm iii */
296   n = (__branred (x, &a, &da)) & 0x00000001;
297   EADD (a, da, t1, t2);
298   a = t1;
299   da = t2;
300   if (a < 0.0)
301     {
302       ya = -a;
303       yya = -da;
304       sy = -1;
305     }
306   else
307     {
308       ya = a;
309       yya = da;
310       sy = 1;
311     }
312 
313   /* (X) The case 1e8 < abs(x) < 2**1024,    0 < abs(y) <= 0.0608 */
314   if (ya <= gy2.d)
315     {
316       a2 = a * a;
317       t2 = d9.d + a2 * d11.d;
318       t2 = d7.d + a2 * t2;
319       t2 = d5.d + a2 * t2;
320       t2 = d3.d + a2 * t2;
321       t2 = da + a * a2 * t2;
322       if (n)
323 	{
324 	  /* -cot */
325 	  EADD (a, t2, b, db);
326 	  DIV2 (1.0, 0.0, b, db, c, dc, t1, t2, t3, t4);
327 	  y = c + dc;
328 	  retval = (-y);
329 	  /* Max ULP is 0.506.  */
330 	  goto ret;
331 	}
332       else
333 	{
334 	  /* tan */
335 	  y = a + t2;
336 	  retval = y;
337 	  /* Max ULP is 0.507.  */
338 	  goto ret;
339 	}
340     }
341 
342   /* (XI) The case 1e8 < abs(x) < 2**1024,    0.0608 < abs(y) <= 0.787 */
343   i = ((int) (mfftnhf.d + 256 * ya));
344   z = (z0 = (ya - xfg[i][0].d)) + yya;
345   z2 = z * z;
346   pz = z + z * z2 * (e0.d + z2 * e1.d);
347   fi = xfg[i][1].d;
348   gi = xfg[i][2].d;
349 
350   if (n)
351     {
352       /* -cot */
353       t2 = pz * (fi + gi) / (fi + pz);
354       y = gi - t2;
355       retval = (-sy * y);
356       /* Max ULP is 0.62.  */
357       goto ret;
358     }
359   else
360     {
361       /* tan */
362       t2 = pz * (gi + fi) / (gi - pz);
363       y = fi + t2;
364       retval = (sy * y);
365       /* Max ULP is 0.62.  */
366       goto ret;
367     }
368 
369 ret:
370   return retval;
371 }
372 
373 #ifndef __tan
374 libm_alias_double (__tan, tan)
375 #endif
376