|
|
1.1 ! root 1: /* ! 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: * ! 6: * @(#)r_tan.c 5.4 2/25/90 ! 7: */ ! 8: ! 9: #ifndef tahoe ! 10: float r_tan(x) ! 11: float *x; ! 12: { ! 13: double tan(); ! 14: return( tan(*x) ); ! 15: } ! 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: #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: ! 49: float ! 50: r_tan(parg) ! 51: float *parg; ! 52: { ! 53: double arg; ! 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.