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 /* @(#)s_asinh.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 /* asinh(x) 00030 * Method : 00031 * Based on 00032 * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] 00033 * we have 00034 * asinh(x) := x if 1+x*x=1, 00035 * := sign(x)*(log(x)+ln2)) for large |x|, else 00036 * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else 00037 * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) 00038 */ 00039 00040 #ifdef POK_NEEDS_LIBMATH 00041 00042 #include <types.h> 00043 #include <libm.h> 00044 #include "math_private.h" 00045 00046 static const double 00047 one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ 00048 ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ 00049 huge= 1.00000000000000000000e+300; 00050 00051 double 00052 asinh(double x) 00053 { 00054 double t,w; 00055 int32_t hx,ix; 00056 GET_HIGH_WORD(hx,x); 00057 ix = hx&0x7fffffff; 00058 if(ix>=0x7ff00000) return x+x; /* x is inf or NaN */ 00059 if(ix< 0x3e300000) { /* |x|<2**-28 */ 00060 if(huge+x>one) return x; /* return x inexact except 0 */ 00061 } 00062 if(ix>0x41b00000) { /* |x| > 2**28 */ 00063 w = __ieee754_log(fabs(x))+ln2; 00064 } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ 00065 t = fabs(x); 00066 w = __ieee754_log(2.0*t+one/(__ieee754_sqrt(x*x+one)+t)); 00067 } else { /* 2.0 > |x| > 2**-28 */ 00068 t = x*x; 00069 w =log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t))); 00070 } 00071 if(hx>0) return w; else return -w; 00072 } 00073 00074 #endif 00075