/* EXP and hyperbolic trig functions for Sozobon C. */ /* Copyright = David Brooks, 1989 All Rights Reserved */ #include #include /* EXP: */ /* */ /* Uses the synthesis (2**n) * (2**[m/8]) * b**g */ /* where b = 2**(1/8) and 8*n+m+g = arg/ln(b). b**g has a cubic */ /* approximation: source and accuracy unknown. */ /* */ /* Beware a bug in the standard release: can't compare two negative */ /* floating numbers. */ float exp(a) register float a; { fstruct res; register int aint; static fstruct huge = {HUGE_AS_INT}; static float powtab[] = {1.0, 1.09050773, 1.1892071, 1.2968396, 1.41421356, 1.5422108, 1.68179283, 1.8340081}; if (a > 43.5) { errno = ERANGE; return huge.f; } if ((a + 43.5) < 0.0) return 0.0; /* Underflow */ if ((aint = (int)(a *= 11.5415603)) < 0) /* 8/ln(2) */ --aint; /* Correct mathematically */ a = (float)aint - a; /* -(frac part) */ res.f = 1.0 + a * (-0.0866439378 + a * (0.003750577 + a * -0.11321783e-3)); res.sc[3] += aint >> 3; /* Mult by 2**n */ return res.f * powtab[aint&7]; /* Mult by 2**[m/8] */ } /* HYPERBOLIC FUNCTIONS: virtually free */ float sinh(a) float a; { register float ea = exp(a); return 0.5 * (ea - (1.0 / ea)); } float cosh(a) float a; { register float ea = exp(a); return 0.5 * (ea + (1.0 / ea)); } float tanh(a) float a; { register float e2a; e2a = exp(a); e2a = e2a * e2a; /* exp-squared-a */ return (e2a - 1.0) / (e2a + 1.0); }