Back to index

glibc  2.9
s_asinhl.c
Go to the documentation of this file.
00001 /* s_asinhl.c -- long double version of s_asinh.c.
00002  * Conversion to long double by Ulrich Drepper,
00003  * Cygnus Support, drepper@cygnus.com.
00004  */
00005 
00006 /*
00007  * ====================================================
00008  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00009  *
00010  * Developed at SunPro, a Sun Microsystems, Inc. business.
00011  * Permission to use, copy, modify, and distribute this
00012  * software is freely granted, provided that this notice
00013  * is preserved.
00014  * ====================================================
00015  */
00016 
00017 #if defined(LIBM_SCCS) && !defined(lint)
00018 static char rcsid[] = "$NetBSD: $";
00019 #endif
00020 
00021 /* asinhl(x)
00022  * Method :
00023  *     Based on
00024  *            asinhl(x) = signl(x) * logl [ |x| + sqrtl(x*x+1) ]
00025  *     we have
00026  *     asinhl(x) := x  if  1+x*x=1,
00027  *              := signl(x)*(logl(x)+ln2)) for large |x|, else
00028  *              := signl(x)*logl(2|x|+1/(|x|+sqrtl(x*x+1))) if|x|>2, else
00029  *              := signl(x)*log1pl(|x| + x^2/(1 + sqrtl(1+x^2)))
00030  */
00031 
00032 #include "math.h"
00033 #include "math_private.h"
00034 
00035 #ifdef __STDC__
00036 static const long double
00037 #else
00038 static long double
00039 #endif
00040 one =  1.000000000000000000000e+00L, /* 0x3FFF, 0x00000000, 0x00000000 */
00041 ln2 =  6.931471805599453094287e-01L, /* 0x3FFE, 0xB17217F7, 0xD1CF79AC */
00042 huge=  1.000000000000000000e+4900L;
00043 
00044 #ifdef __STDC__
00045        long double __asinhl(long double x)
00046 #else
00047        long double __asinhl(x)
00048        long double x;
00049 #endif
00050 {
00051        long double t,w;
00052        int32_t hx,ix;
00053        GET_LDOUBLE_EXP(hx,x);
00054        ix = hx&0x7fff;
00055        if(ix==0x7fff) return x+x;  /* x is inf or NaN */
00056        if(ix< 0x3fde) {     /* |x|<2**-34 */
00057            if(huge+x>one) return x;       /* return x inexact except 0 */
00058        }
00059        if(ix>0x4020) {             /* |x| > 2**34 */
00060            w = __ieee754_logl(fabsl(x))+ln2;
00061        } else if (ix>0x4000) {     /* 2**34 > |x| > 2.0 */
00062            t = fabsl(x);
00063            w = __ieee754_logl(2.0*t+one/(__ieee754_sqrtl(x*x+one)+t));
00064        } else {             /* 2.0 > |x| > 2**-28 */
00065            t = x*x;
00066            w =__log1pl(fabsl(x)+t/(one+__ieee754_sqrtl(one+t)));
00067        }
00068        if(hx&0x8000) return -w; else return w;
00069 }
00070 weak_alias (__asinhl, asinhl)