1141296Sdas 2141296Sdas/* @(#)e_cosh.c 1.3 95/01/18 */ 32116Sjkh/* 42116Sjkh * ==================================================== 52116Sjkh * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 62116Sjkh * 7141296Sdas * Developed at SunSoft, a Sun Microsystems, Inc. business. 82116Sjkh * Permission to use, copy, modify, and distribute this 9141296Sdas * software is freely granted, provided that this notice 102116Sjkh * is preserved. 112116Sjkh * ==================================================== 122116Sjkh */ 132116Sjkh 14176451Sdas#include <sys/cdefs.h> 15176451Sdas__FBSDID("$FreeBSD$"); 162116Sjkh 172116Sjkh/* __ieee754_cosh(x) 18141296Sdas * Method : 192116Sjkh * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 20141296Sdas * 1. Replace x by |x| (cosh(x) = cosh(-x)). 21141296Sdas * 2. 22141296Sdas * [ exp(x) - 1 ]^2 232116Sjkh * 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- 242116Sjkh * 2*exp(x) 252116Sjkh * 262116Sjkh * exp(x) + 1/exp(x) 272116Sjkh * ln2/2 <= x <= 22 : cosh(x) := ------------------- 282116Sjkh * 2 29141296Sdas * 22 <= x <= lnovft : cosh(x) := exp(x)/2 302116Sjkh * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) 312116Sjkh * ln2ovft < x : cosh(x) := huge*huge (overflow) 322116Sjkh * 332116Sjkh * Special cases: 342116Sjkh * cosh(x) is |x| if x is +INF, -INF, or NaN. 352116Sjkh * only cosh(0)=1 is exact for finite x. 362116Sjkh */ 372116Sjkh 38271779Stijl#include <float.h> 39271779Stijl 402116Sjkh#include "math.h" 412116Sjkh#include "math_private.h" 422116Sjkh 432116Sjkhstatic const double one = 1.0, half=0.5, huge = 1.0e300; 442116Sjkh 4597407Salfreddouble 4697407Salfred__ieee754_cosh(double x) 478870Srgrimes{ 482116Sjkh double t,w; 492116Sjkh int32_t ix; 502116Sjkh 512116Sjkh /* High word of |x|. */ 522116Sjkh GET_HIGH_WORD(ix,x); 532116Sjkh ix &= 0x7fffffff; 542116Sjkh 552116Sjkh /* x is INF or NaN */ 56141296Sdas if(ix>=0x7ff00000) return x*x; 572116Sjkh 582116Sjkh /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ 592116Sjkh if(ix<0x3fd62e43) { 602116Sjkh t = expm1(fabs(x)); 612116Sjkh w = one+t; 622116Sjkh if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ 632116Sjkh return one+(t*t)/(w+w); 642116Sjkh } 652116Sjkh 662116Sjkh /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ 672116Sjkh if (ix < 0x40360000) { 682116Sjkh t = __ieee754_exp(fabs(x)); 692116Sjkh return half*t+half/t; 702116Sjkh } 712116Sjkh 722116Sjkh /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ 732116Sjkh if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x)); 742116Sjkh 752116Sjkh /* |x| in [log(maxdouble), overflowthresold] */ 76226598Sdas if (ix<=0x408633CE) 77226598Sdas return __ldexp_exp(fabs(x), -1); 782116Sjkh 792116Sjkh /* |x| > overflowthresold, cosh(x) overflow */ 802116Sjkh return huge*huge; 812116Sjkh} 82271779Stijl 83271779Stijl#if (LDBL_MANT_DIG == 53) 84271779Stijl__weak_reference(cosh, coshl); 85271779Stijl#endif 86