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 143a8617a8SJordan K. Hubbard #ifndef lint 157f3dea24SPeter Wemm static char rcsid[] = "$FreeBSD$"; 163a8617a8SJordan K. Hubbard #endif 173a8617a8SJordan K. Hubbard 183a8617a8SJordan K. Hubbard /* __ieee754_cosh(x) 193a8617a8SJordan K. Hubbard * Method : 203a8617a8SJordan K. Hubbard * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 213a8617a8SJordan K. Hubbard * 1. Replace x by |x| (cosh(x) = cosh(-x)). 223a8617a8SJordan K. Hubbard * 2. 233a8617a8SJordan K. Hubbard * [ exp(x) - 1 ]^2 243a8617a8SJordan K. Hubbard * 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- 253a8617a8SJordan K. Hubbard * 2*exp(x) 263a8617a8SJordan K. Hubbard * 273a8617a8SJordan K. Hubbard * exp(x) + 1/exp(x) 283a8617a8SJordan K. Hubbard * ln2/2 <= x <= 22 : cosh(x) := ------------------- 293a8617a8SJordan K. Hubbard * 2 303a8617a8SJordan K. Hubbard * 22 <= x <= lnovft : cosh(x) := exp(x)/2 313a8617a8SJordan K. Hubbard * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) 323a8617a8SJordan K. Hubbard * ln2ovft < x : cosh(x) := huge*huge (overflow) 333a8617a8SJordan K. Hubbard * 343a8617a8SJordan K. Hubbard * Special cases: 353a8617a8SJordan K. Hubbard * cosh(x) is |x| if x is +INF, -INF, or NaN. 363a8617a8SJordan K. Hubbard * only cosh(0)=1 is exact for finite x. 373a8617a8SJordan K. Hubbard */ 383a8617a8SJordan K. Hubbard 393a8617a8SJordan K. Hubbard #include "math.h" 403a8617a8SJordan K. Hubbard #include "math_private.h" 413a8617a8SJordan K. Hubbard 423a8617a8SJordan K. Hubbard static const double one = 1.0, half=0.5, huge = 1.0e300; 433a8617a8SJordan K. Hubbard 44a82bbc73SAlfred Perlstein double 45a82bbc73SAlfred Perlstein __ieee754_cosh(double x) 463a8617a8SJordan K. Hubbard { 473a8617a8SJordan K. Hubbard double t,w; 483a8617a8SJordan K. Hubbard int32_t ix; 493a8617a8SJordan K. Hubbard u_int32_t lx; 503a8617a8SJordan K. Hubbard 513a8617a8SJordan K. Hubbard /* High word of |x|. */ 523a8617a8SJordan K. Hubbard GET_HIGH_WORD(ix,x); 533a8617a8SJordan K. Hubbard ix &= 0x7fffffff; 543a8617a8SJordan K. Hubbard 553a8617a8SJordan K. Hubbard /* x is INF or NaN */ 563a8617a8SJordan K. Hubbard if(ix>=0x7ff00000) return x*x; 573a8617a8SJordan K. Hubbard 583a8617a8SJordan K. Hubbard /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ 593a8617a8SJordan K. Hubbard if(ix<0x3fd62e43) { 603a8617a8SJordan K. Hubbard t = expm1(fabs(x)); 613a8617a8SJordan K. Hubbard w = one+t; 623a8617a8SJordan K. Hubbard if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ 633a8617a8SJordan K. Hubbard return one+(t*t)/(w+w); 643a8617a8SJordan K. Hubbard } 653a8617a8SJordan K. Hubbard 663a8617a8SJordan K. Hubbard /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ 673a8617a8SJordan K. Hubbard if (ix < 0x40360000) { 683a8617a8SJordan K. Hubbard t = __ieee754_exp(fabs(x)); 693a8617a8SJordan K. Hubbard return half*t+half/t; 703a8617a8SJordan K. Hubbard } 713a8617a8SJordan K. Hubbard 723a8617a8SJordan K. Hubbard /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ 733a8617a8SJordan K. Hubbard if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x)); 743a8617a8SJordan K. Hubbard 753a8617a8SJordan K. Hubbard /* |x| in [log(maxdouble), overflowthresold] */ 763a8617a8SJordan K. Hubbard GET_LOW_WORD(lx,x); 773a8617a8SJordan K. Hubbard if (ix<0x408633CE || 7851295a4dSJordan K. Hubbard ((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) { 793a8617a8SJordan K. Hubbard w = __ieee754_exp(half*fabs(x)); 803a8617a8SJordan K. Hubbard t = half*w; 813a8617a8SJordan K. Hubbard return t*w; 823a8617a8SJordan K. Hubbard } 833a8617a8SJordan K. Hubbard 843a8617a8SJordan K. Hubbard /* |x| > overflowthresold, cosh(x) overflow */ 853a8617a8SJordan K. Hubbard return huge*huge; 863a8617a8SJordan K. Hubbard } 87