POK
|
00001 /* 00002 * POK header 00003 * 00004 * The following file is a part of the POK project. Any modification should 00005 * made according to the POK licence. You CANNOT use this file or a part of 00006 * this file is this part of a file for your own project 00007 * 00008 * For more information on the POK licence, please see our LICENCE FILE 00009 * 00010 * Please follow the coding guidelines described in doc/CODING_GUIDELINES 00011 * 00012 * Copyright (c) 2007-2009 POK team 00013 * 00014 * Created by julien on Fri Jan 30 14:41:34 2009 00015 */ 00016 00017 /* @(#)e_cosh.c 5.1 93/09/24 */ 00018 /* 00019 * ==================================================== 00020 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 00021 * 00022 * Developed at SunPro, a Sun Microsystems, Inc. business. 00023 * Permission to use, copy, modify, and distribute this 00024 * software is freely granted, provided that this notice 00025 * is preserved. 00026 * ==================================================== 00027 */ 00028 00029 /* __ieee754_cosh(x) 00030 * Method : 00031 * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 00032 * 1. Replace x by |x| (cosh(x) = cosh(-x)). 00033 * 2. 00034 * [ exp(x) - 1 ]^2 00035 * 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- 00036 * 2*exp(x) 00037 * 00038 * exp(x) + 1/exp(x) 00039 * ln2/2 <= x <= 22 : cosh(x) := ------------------- 00040 * 2 00041 * 22 <= x <= lnovft : cosh(x) := exp(x)/2 00042 * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) 00043 * ln2ovft < x : cosh(x) := huge*huge (overflow) 00044 * 00045 * Special cases: 00046 * cosh(x) is |x| if x is +INF, -INF, or NaN. 00047 * only cosh(0)=1 is exact for finite x. 00048 */ 00049 00050 #ifdef POK_NEEDS_LIBMATH 00051 #include "math_private.h" 00052 #include <libm.h> 00053 00054 static const double one = 1.0, half=0.5, huge = 1.0e300; 00055 00056 double 00057 __ieee754_cosh(double x) 00058 { 00059 double t,w; 00060 int32_t ix; 00061 uint32_t lx; 00062 00063 /* High word of |x|. */ 00064 GET_HIGH_WORD(ix,x); 00065 ix &= 0x7fffffff; 00066 00067 /* x is INF or NaN */ 00068 if(ix>=0x7ff00000) return x*x; 00069 00070 /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ 00071 if(ix<0x3fd62e43) { 00072 t = expm1(fabs(x)); 00073 w = one+t; 00074 if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ 00075 return one+(t*t)/(w+w); 00076 } 00077 00078 /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ 00079 if (ix < 0x40360000) { 00080 t = __ieee754_exp(fabs(x)); 00081 return half*t+half/t; 00082 } 00083 00084 /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ 00085 if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x)); 00086 00087 /* |x| in [log(maxdouble), overflowthresold] */ 00088 GET_LOW_WORD(lx,x); 00089 if (ix<0x408633CE || 00090 ((ix==0x408633ce)&&(lx<=(uint32_t)0x8fb9f87d))) { 00091 w = __ieee754_exp(half*fabs(x)); 00092 t = half*w; 00093 return t*w; 00094 } 00095 00096 /* |x| > overflowthresold, cosh(x) overflow */ 00097 return huge*huge; 00098 } 00099 #endif