Commit | Line | Data |
---|---|---|
9cc59523 | 1 | /* |
be6e3ddf RE |
2 | * Copyright (c) 1980 Regents of the University of California. |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | * | |
4d98b990 | 6 | * @(#)r_tan.c 5.3 %G% |
9cc59523 DW |
7 | */ |
8 | ||
4d98b990 | 9 | #ifndef tahoe |
46452188 | 10 | float r_tan(x) |
9cc59523 DW |
11 | float *x; |
12 | { | |
13 | double tan(); | |
14 | return( tan(*x) ); | |
15 | } | |
4d98b990 KM |
16 | |
17 | #else tahoe | |
18 | ||
19 | /* | |
20 | SINGLE PRECISION floating point tangent | |
21 | ||
22 | sin/cos is used after argument reduction to [0,pi/4] range. | |
23 | since x is in this range, tan(x) is in [0,1] range and | |
24 | no overflow can occur here. | |
25 | */ | |
26 | ||
27 | #include <errno.h> | |
28 | ||
29 | int errno; | |
30 | static double invpi = 1.27323954473516268; /* 4/pi */ | |
31 | ||
32 | float | |
33 | r_tan(parg) | |
34 | float *parg; | |
35 | { | |
36 | double arg; | |
37 | fortran float sin(), cos(); | |
38 | double modf(); | |
39 | float flmax_(); | |
40 | double temp, e, x, xsq; | |
41 | int sign; | |
42 | int flag, i; | |
43 | ||
44 | arg = *parg; | |
45 | flag = 0; | |
46 | sign = 1.; | |
47 | if(arg < 0.){ /* tan(-arg) = -tan(arg) */ | |
48 | arg = -arg; | |
49 | sign = -1.; | |
50 | } | |
51 | arg = arg*invpi; /*overflow?*/ | |
52 | x = modf(arg,&e); | |
53 | i = e; | |
54 | switch(i%4) { | |
55 | case 1: /* 2nd octant: tan(x) = 1/tan(1-x) */ | |
56 | x = 1. - x; | |
57 | flag = 1; | |
58 | break; | |
59 | ||
60 | case 2: /* 3rd octant: tan(x) = -1/tan(x) */ | |
61 | sign = - sign; | |
62 | flag = 1; | |
63 | break; | |
64 | ||
65 | case 3: /* 4th octant: tan(x) = -tan(1-x) */ | |
66 | x = 1. - x; | |
67 | sign = - sign; | |
68 | break; | |
69 | ||
70 | case 0: /* 1st octant */ | |
71 | break; | |
72 | } | |
73 | x = x/invpi; | |
74 | ||
75 | temp = sin(x)/cos(x); | |
76 | ||
77 | if(flag == 1) { | |
78 | if(temp == 0.) { /* check for singular "point" */ | |
79 | errno = ERANGE; | |
80 | if (sign>0) | |
81 | return(flmax_()); | |
82 | return(-flmax_()); | |
83 | } | |
84 | temp = 1./temp; | |
85 | } | |
86 | return(sign*temp); | |
87 | } | |
88 | ||
89 | #endif tahoe |