Back to index

glibc  2.9
e_acoshl.c
Go to the documentation of this file.
00001 /* e_acoshl.c -- long double version of e_acosh.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 /* __ieee754_acoshl(x)
00022  * Method :
00023  *     Based on
00024  *            acoshl(x) = logl [ x + sqrtl(x*x-1) ]
00025  *     we have
00026  *            acoshl(x) := logl(x)+ln2,   if x is large; else
00027  *            acoshl(x) := logl(2x-1/(sqrtl(x*x-1)+x)) if x>2; else
00028  *            acoshl(x) := log1pl(t+sqrtl(2.0*t+t*t)); where t=x-1.
00029  *
00030  * Special cases:
00031  *     acoshl(x) is NaN with signal if x<1.
00032  *     acoshl(NaN) is NaN without signal.
00033  */
00034 
00035 #include "math.h"
00036 #include "math_private.h"
00037 
00038 #ifdef __STDC__
00039 static const long double
00040 #else
00041 static long double
00042 #endif
00043 one    = 1.0,
00044 ln2    = 6.931471805599453094287e-01L; /* 0x3FFE, 0xB17217F7, 0xD1CF79AC */
00045 
00046 #ifdef __STDC__
00047        long double __ieee754_acoshl(long double x)
00048 #else
00049        long double __ieee754_acoshl(x)
00050        long double x;
00051 #endif
00052 {
00053        long double t;
00054        u_int32_t se,i0,i1;
00055        GET_LDOUBLE_WORDS(se,i0,i1,x);
00056        if(se<0x3fff || se & 0x8000) {     /* x < 1 */
00057            return (x-x)/(x-x);
00058        } else if(se >=0x401d) {    /* x > 2**30 */
00059            if(se >=0x7fff) {              /* x is inf of NaN */
00060                return x+x;
00061            } else
00062               return __ieee754_logl(x)+ln2;      /* acoshl(huge)=logl(2x) */
00063        } else if(((se-0x3fff)|i0|i1)==0) {
00064            return 0.0;                    /* acosh(1) = 0 */
00065        } else if (se > 0x4000) {   /* 2**28 > x > 2 */
00066            t=x*x;
00067            return __ieee754_logl(2.0*x-one/(x+__ieee754_sqrtl(t-one)));
00068        } else {                    /* 1<x<2 */
00069            t = x-one;
00070            return __log1pl(t+__sqrtl(2.0*t+t*t));
00071        }
00072 }