1*c9945492SAndroid Build Coastguard Worker #include "libm.h" 2*c9945492SAndroid Build Coastguard Worker 3*c9945492SAndroid Build Coastguard Worker /* cosh(x) = (exp(x) + 1/exp(x))/2 4*c9945492SAndroid Build Coastguard Worker * = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x) 5*c9945492SAndroid Build Coastguard Worker * = 1 + x*x/2 + o(x^4) 6*c9945492SAndroid Build Coastguard Worker */ cosh(double x)7*c9945492SAndroid Build Coastguard Workerdouble cosh(double x) 8*c9945492SAndroid Build Coastguard Worker { 9*c9945492SAndroid Build Coastguard Worker union {double f; uint64_t i;} u = {.f = x}; 10*c9945492SAndroid Build Coastguard Worker uint32_t w; 11*c9945492SAndroid Build Coastguard Worker double t; 12*c9945492SAndroid Build Coastguard Worker 13*c9945492SAndroid Build Coastguard Worker /* |x| */ 14*c9945492SAndroid Build Coastguard Worker u.i &= (uint64_t)-1/2; 15*c9945492SAndroid Build Coastguard Worker x = u.f; 16*c9945492SAndroid Build Coastguard Worker w = u.i >> 32; 17*c9945492SAndroid Build Coastguard Worker 18*c9945492SAndroid Build Coastguard Worker /* |x| < log(2) */ 19*c9945492SAndroid Build Coastguard Worker if (w < 0x3fe62e42) { 20*c9945492SAndroid Build Coastguard Worker if (w < 0x3ff00000 - (26<<20)) { 21*c9945492SAndroid Build Coastguard Worker /* raise inexact if x!=0 */ 22*c9945492SAndroid Build Coastguard Worker FORCE_EVAL(x + 0x1p120f); 23*c9945492SAndroid Build Coastguard Worker return 1; 24*c9945492SAndroid Build Coastguard Worker } 25*c9945492SAndroid Build Coastguard Worker t = expm1(x); 26*c9945492SAndroid Build Coastguard Worker return 1 + t*t/(2*(1+t)); 27*c9945492SAndroid Build Coastguard Worker } 28*c9945492SAndroid Build Coastguard Worker 29*c9945492SAndroid Build Coastguard Worker /* |x| < log(DBL_MAX) */ 30*c9945492SAndroid Build Coastguard Worker if (w < 0x40862e42) { 31*c9945492SAndroid Build Coastguard Worker t = exp(x); 32*c9945492SAndroid Build Coastguard Worker /* note: if x>log(0x1p26) then the 1/t is not needed */ 33*c9945492SAndroid Build Coastguard Worker return 0.5*(t + 1/t); 34*c9945492SAndroid Build Coastguard Worker } 35*c9945492SAndroid Build Coastguard Worker 36*c9945492SAndroid Build Coastguard Worker /* |x| > log(DBL_MAX) or nan */ 37*c9945492SAndroid Build Coastguard Worker /* note: the result is stored to handle overflow */ 38*c9945492SAndroid Build Coastguard Worker t = __expo2(x, 1.0); 39*c9945492SAndroid Build Coastguard Worker return t; 40*c9945492SAndroid Build Coastguard Worker } 41