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 | * | |
d649dedb | 6 | * @(#)r_tan.c 5.4 %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 | ||
d649dedb DS |
32 | #ifndef __GNUC__ |
33 | fortran float sin(), cos(); | |
34 | #else | |
35 | #define sin(x) \ | |
36 | ({ \ | |
37 | float __result; \ | |
38 | asm("ldd %1; cvdf; sinf; stf %0" : "=rm" (__result) : "rm" (x)); \ | |
39 | __result; \ | |
40 | }) | |
41 | #define cos(x) \ | |
42 | ({ \ | |
43 | float __result; \ | |
44 | asm("ldd %1; cvdf; cosf; stf %0" : "=rm" (__result) : "rm" (x)); \ | |
45 | __result; \ | |
46 | }) | |
47 | #endif | |
48 | ||
4d98b990 KM |
49 | float |
50 | r_tan(parg) | |
51 | float *parg; | |
52 | { | |
53 | double arg; | |
4d98b990 KM |
54 | double modf(); |
55 | float flmax_(); | |
56 | double temp, e, x, xsq; | |
57 | int sign; | |
58 | int flag, i; | |
59 | ||
60 | arg = *parg; | |
61 | flag = 0; | |
62 | sign = 1.; | |
63 | if(arg < 0.){ /* tan(-arg) = -tan(arg) */ | |
64 | arg = -arg; | |
65 | sign = -1.; | |
66 | } | |
67 | arg = arg*invpi; /*overflow?*/ | |
68 | x = modf(arg,&e); | |
69 | i = e; | |
70 | switch(i%4) { | |
71 | case 1: /* 2nd octant: tan(x) = 1/tan(1-x) */ | |
72 | x = 1. - x; | |
73 | flag = 1; | |
74 | break; | |
75 | ||
76 | case 2: /* 3rd octant: tan(x) = -1/tan(x) */ | |
77 | sign = - sign; | |
78 | flag = 1; | |
79 | break; | |
80 | ||
81 | case 3: /* 4th octant: tan(x) = -tan(1-x) */ | |
82 | x = 1. - x; | |
83 | sign = - sign; | |
84 | break; | |
85 | ||
86 | case 0: /* 1st octant */ | |
87 | break; | |
88 | } | |
89 | x = x/invpi; | |
90 | ||
91 | temp = sin(x)/cos(x); | |
92 | ||
93 | if(flag == 1) { | |
94 | if(temp == 0.) { /* check for singular "point" */ | |
95 | errno = ERANGE; | |
96 | if (sign>0) | |
97 | return(flmax_()); | |
98 | return(-flmax_()); | |
99 | } | |
100 | temp = 1./temp; | |
101 | } | |
102 | return(sign*temp); | |
103 | } | |
104 | ||
105 | #endif tahoe |