For GCC's (and ANSI's) sake, don't name a formal parameter after a typedef.
[unix-history] / usr / src / usr.bin / f77 / libF77 / r_tan.c
CommitLineData
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 10float r_tan(x)
9cc59523
DW
11float *x;
12{
13double tan();
14return( 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
29int errno;
30static double invpi = 1.27323954473516268; /* 4/pi */
31
32float
33r_tan(parg)
34float *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