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 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math.h" 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math_private.h" 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const double one = 1.0, half=0.5, huge = 1.0e300; 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdouble 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__ieee754_cosh(double x) 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project double t,w; 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int32_t ix; 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* High word of |x|. */ 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project GET_HIGH_WORD(ix,x); 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ix &= 0x7fffffff; 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* x is INF or NaN */ 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(ix>=0x7ff00000) return x*x; 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(ix<0x3fd62e43) { 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project t = expm1(fabs(x)); 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project w = one+t; 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return one+(t*t)/(w+w); 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ix < 0x40360000) { 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project t = __ieee754_exp(fabs(x)); 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return half*t+half/t; 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x)); 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* |x| in [log(maxdouble), overflowthresold] */ 74a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes if (ix<=0x408633CE) 75a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes return __ldexp_exp(fabs(x), -1); 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* |x| > overflowthresold, cosh(x) overflow */ 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return huge*huge; 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 80