13f708241SDavid Schultz 23f708241SDavid Schultz /* @(#)e_cosh.c 1.3 95/01/18 */ 33a8617a8SJordan K. Hubbard /* 43a8617a8SJordan K. Hubbard * ==================================================== 53a8617a8SJordan K. Hubbard * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 63a8617a8SJordan K. Hubbard * 73f708241SDavid Schultz * Developed at SunSoft, a Sun Microsystems, Inc. business. 83a8617a8SJordan K. Hubbard * Permission to use, copy, modify, and distribute this 93a8617a8SJordan K. Hubbard * software is freely granted, provided that this notice 103a8617a8SJordan K. Hubbard * is preserved. 113a8617a8SJordan K. Hubbard * ==================================================== 123a8617a8SJordan K. Hubbard */ 133a8617a8SJordan K. Hubbard 145aa554c7SDavid Schultz #include <sys/cdefs.h> 155aa554c7SDavid Schultz __FBSDID("$FreeBSD$"); 163a8617a8SJordan K. Hubbard 173a8617a8SJordan K. Hubbard /* __ieee754_cosh(x) 183a8617a8SJordan K. Hubbard * Method : 193a8617a8SJordan K. Hubbard * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 203a8617a8SJordan K. Hubbard * 1. Replace x by |x| (cosh(x) = cosh(-x)). 213a8617a8SJordan K. Hubbard * 2. 223a8617a8SJordan K. Hubbard * [ exp(x) - 1 ]^2 233a8617a8SJordan K. Hubbard * 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- 243a8617a8SJordan K. Hubbard * 2*exp(x) 253a8617a8SJordan K. Hubbard * 263a8617a8SJordan K. Hubbard * exp(x) + 1/exp(x) 273a8617a8SJordan K. Hubbard * ln2/2 <= x <= 22 : cosh(x) := ------------------- 283a8617a8SJordan K. Hubbard * 2 293a8617a8SJordan K. Hubbard * 22 <= x <= lnovft : cosh(x) := exp(x)/2 303a8617a8SJordan K. Hubbard * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) 313a8617a8SJordan K. Hubbard * ln2ovft < x : cosh(x) := huge*huge (overflow) 323a8617a8SJordan K. Hubbard * 333a8617a8SJordan K. Hubbard * Special cases: 343a8617a8SJordan K. Hubbard * cosh(x) is |x| if x is +INF, -INF, or NaN. 353a8617a8SJordan K. Hubbard * only cosh(0)=1 is exact for finite x. 363a8617a8SJordan K. Hubbard */ 373a8617a8SJordan K. Hubbard 383a8617a8SJordan K. Hubbard #include "math.h" 393a8617a8SJordan K. Hubbard #include "math_private.h" 403a8617a8SJordan K. Hubbard 413a8617a8SJordan K. Hubbard static const double one = 1.0, half=0.5, huge = 1.0e300; 423a8617a8SJordan K. Hubbard 43a82bbc73SAlfred Perlstein double 44a82bbc73SAlfred Perlstein __ieee754_cosh(double x) 453a8617a8SJordan K. Hubbard { 463a8617a8SJordan K. Hubbard double t,w; 473a8617a8SJordan K. Hubbard int32_t ix; 483a8617a8SJordan K. Hubbard 493a8617a8SJordan K. Hubbard /* High word of |x|. */ 503a8617a8SJordan K. Hubbard GET_HIGH_WORD(ix,x); 513a8617a8SJordan K. Hubbard ix &= 0x7fffffff; 523a8617a8SJordan K. Hubbard 533a8617a8SJordan K. Hubbard /* x is INF or NaN */ 543a8617a8SJordan K. Hubbard if(ix>=0x7ff00000) return x*x; 553a8617a8SJordan K. Hubbard 563a8617a8SJordan K. Hubbard /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ 573a8617a8SJordan K. Hubbard if(ix<0x3fd62e43) { 583a8617a8SJordan K. Hubbard t = expm1(fabs(x)); 593a8617a8SJordan K. Hubbard w = one+t; 603a8617a8SJordan K. Hubbard if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ 613a8617a8SJordan K. Hubbard return one+(t*t)/(w+w); 623a8617a8SJordan K. Hubbard } 633a8617a8SJordan K. Hubbard 643a8617a8SJordan K. Hubbard /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ 653a8617a8SJordan K. Hubbard if (ix < 0x40360000) { 663a8617a8SJordan K. Hubbard t = __ieee754_exp(fabs(x)); 673a8617a8SJordan K. Hubbard return half*t+half/t; 683a8617a8SJordan K. Hubbard } 693a8617a8SJordan K. Hubbard 703a8617a8SJordan K. Hubbard /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ 713a8617a8SJordan K. Hubbard if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x)); 723a8617a8SJordan K. Hubbard 733a8617a8SJordan K. Hubbard /* |x| in [log(maxdouble), overflowthresold] */ 74*d4657ac7SDavid Schultz if (ix<=0x408633CE) 75*d4657ac7SDavid Schultz return __ldexp_exp(fabs(x), -1); 763a8617a8SJordan K. Hubbard 773a8617a8SJordan K. Hubbard /* |x| > overflowthresold, cosh(x) overflow */ 783a8617a8SJordan K. Hubbard return huge*huge; 793a8617a8SJordan K. Hubbard } 80