11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* @(#)e_cosh.c 1.3 95/01/18 */ 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ==================================================== 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Developed at SunSoft, a Sun Microsystems, Inc. business. 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * software is freely granted, provided that this notice 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is preserved. 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ==================================================== 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 14a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#include <sys/cdefs.h> 15a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes__FBSDID("$FreeBSD$"); 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* __ieee754_cosh(x) 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Method : 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Replace x by |x| (cosh(x) = cosh(-x)). 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * [ exp(x) - 1 ]^2 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2*exp(x) 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * exp(x) + 1/exp(x) 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ln2/2 <= x <= 22 : cosh(x) := ------------------- 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 22 <= x <= lnovft : cosh(x) := exp(x)/2 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ln2ovft < x : cosh(x) := huge*huge (overflow) 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Special cases: 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * cosh(x) is |x| if x is +INF, -INF, or NaN. 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * only cosh(0)=1 is exact for finite x. 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 38460ad7454a281470a1938103f099a1e3192fb3d6Elliott Hughes#include <float.h> 39460ad7454a281470a1938103f099a1e3192fb3d6Elliott Hughes 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math.h" 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math_private.h" 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const double one = 1.0, half=0.5, huge = 1.0e300; 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdouble 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__ieee754_cosh(double x) 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project double t,w; 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int32_t ix; 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* High word of |x|. */ 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project GET_HIGH_WORD(ix,x); 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ix &= 0x7fffffff; 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* x is INF or NaN */ 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(ix>=0x7ff00000) return x*x; 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(ix<0x3fd62e43) { 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project t = expm1(fabs(x)); 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project w = one+t; 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return one+(t*t)/(w+w); 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ix < 0x40360000) { 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project t = __ieee754_exp(fabs(x)); 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return half*t+half/t; 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x)); 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* |x| in [log(maxdouble), overflowthresold] */ 76a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes if (ix<=0x408633CE) 77a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes return __ldexp_exp(fabs(x), -1); 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* |x| > overflowthresold, cosh(x) overflow */ 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return huge*huge; 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 82460ad7454a281470a1938103f099a1e3192fb3d6Elliott Hughes 83460ad7454a281470a1938103f099a1e3192fb3d6Elliott Hughes#if (LDBL_MANT_DIG == 53) 84460ad7454a281470a1938103f099a1e3192fb3d6Elliott Hughes__weak_reference(cosh, coshl); 85460ad7454a281470a1938103f099a1e3192fb3d6Elliott Hughes#endif 86