13a8617a8SJordan K. Hubbard /* @(#)e_cosh.c 5.1 93/09/24 */ 23a8617a8SJordan K. Hubbard /* 33a8617a8SJordan K. Hubbard * ==================================================== 43a8617a8SJordan K. Hubbard * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 53a8617a8SJordan K. Hubbard * 63a8617a8SJordan K. Hubbard * Developed at SunPro, a Sun Microsystems, Inc. business. 73a8617a8SJordan K. Hubbard * Permission to use, copy, modify, and distribute this 83a8617a8SJordan K. Hubbard * software is freely granted, provided that this notice 93a8617a8SJordan K. Hubbard * is preserved. 103a8617a8SJordan K. Hubbard * ==================================================== 113a8617a8SJordan K. Hubbard */ 123a8617a8SJordan K. Hubbard 133a8617a8SJordan K. Hubbard #ifndef lint 147f3dea24SPeter Wemm static char rcsid[] = "$FreeBSD$"; 153a8617a8SJordan K. Hubbard #endif 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 u_int32_t lx; 493a8617a8SJordan K. Hubbard 503a8617a8SJordan K. Hubbard /* High word of |x|. */ 513a8617a8SJordan K. Hubbard GET_HIGH_WORD(ix,x); 523a8617a8SJordan K. Hubbard ix &= 0x7fffffff; 533a8617a8SJordan K. Hubbard 543a8617a8SJordan K. Hubbard /* x is INF or NaN */ 553a8617a8SJordan K. Hubbard if(ix>=0x7ff00000) return x*x; 563a8617a8SJordan K. Hubbard 573a8617a8SJordan K. Hubbard /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ 583a8617a8SJordan K. Hubbard if(ix<0x3fd62e43) { 593a8617a8SJordan K. Hubbard t = expm1(fabs(x)); 603a8617a8SJordan K. Hubbard w = one+t; 613a8617a8SJordan K. Hubbard if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ 623a8617a8SJordan K. Hubbard return one+(t*t)/(w+w); 633a8617a8SJordan K. Hubbard } 643a8617a8SJordan K. Hubbard 653a8617a8SJordan K. Hubbard /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ 663a8617a8SJordan K. Hubbard if (ix < 0x40360000) { 673a8617a8SJordan K. Hubbard t = __ieee754_exp(fabs(x)); 683a8617a8SJordan K. Hubbard return half*t+half/t; 693a8617a8SJordan K. Hubbard } 703a8617a8SJordan K. Hubbard 713a8617a8SJordan K. Hubbard /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ 723a8617a8SJordan K. Hubbard if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x)); 733a8617a8SJordan K. Hubbard 743a8617a8SJordan K. Hubbard /* |x| in [log(maxdouble), overflowthresold] */ 753a8617a8SJordan K. Hubbard GET_LOW_WORD(lx,x); 763a8617a8SJordan K. Hubbard if (ix<0x408633CE || 7751295a4dSJordan K. Hubbard ((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) { 783a8617a8SJordan K. Hubbard w = __ieee754_exp(half*fabs(x)); 793a8617a8SJordan K. Hubbard t = half*w; 803a8617a8SJordan K. Hubbard return t*w; 813a8617a8SJordan K. Hubbard } 823a8617a8SJordan K. Hubbard 833a8617a8SJordan K. Hubbard /* |x| > overflowthresold, cosh(x) overflow */ 843a8617a8SJordan K. Hubbard return huge*huge; 853a8617a8SJordan K. Hubbard } 86