svn commit: r251599 - in head/lib/msun: . man src

David Schultz das at FreeBSD.org
Mon Jun 10 06:05:01 UTC 2013


Author: das
Date: Mon Jun 10 06:04:58 2013
New Revision: 251599
URL: http://svnweb.freebsd.org/changeset/base/251599

Log:
  Add implementations of acoshl(), asinhl(), and atanhl().  This is a
  merge of the work done by bde and myself.

Added:
  head/lib/msun/src/e_acoshl.c
     - copied, changed from r251484, head/lib/msun/src/e_acosh.c
  head/lib/msun/src/e_atanhl.c
     - copied, changed from r251484, head/lib/msun/src/e_atanh.c
  head/lib/msun/src/s_asinhl.c
     - copied, changed from r251484, head/lib/msun/src/s_asinh.c
Modified:
  head/lib/msun/Makefile
  head/lib/msun/Symbol.map
  head/lib/msun/man/acosh.3
  head/lib/msun/man/asinh.3
  head/lib/msun/man/atanh.3
  head/lib/msun/src/e_acosh.c
  head/lib/msun/src/e_atanh.c
  head/lib/msun/src/math.h
  head/lib/msun/src/s_asinh.c

Modified: head/lib/msun/Makefile
==============================================================================
--- head/lib/msun/Makefile	Mon Jun 10 06:03:03 2013	(r251598)
+++ head/lib/msun/Makefile	Mon Jun 10 06:04:58 2013	(r251599)
@@ -94,10 +94,10 @@ SYMBOL_MAPS=	${SYM_MAPS}
 COMMON_SRCS+=	s_copysignl.c s_fabsl.c s_llrintl.c s_lrintl.c s_modfl.c
 .if ${LDBL_PREC} != 53
 # If long double != double use these; otherwise, we alias the double versions.
-COMMON_SRCS+=	e_acosl.c e_asinl.c e_atan2l.c e_fmodl.c \
-	e_hypotl.c e_remainderl.c e_sqrtl.c \
+COMMON_SRCS+=	e_acoshl.c e_acosl.c e_asinl.c e_atan2l.c e_atanhl.c \
+	e_fmodl.c e_hypotl.c e_remainderl.c e_sqrtl.c \
 	invtrig.c k_cosl.c k_sinl.c k_tanl.c \
-	s_atanl.c s_cbrtl.c s_ceill.c s_cosl.c s_cprojl.c \
+	s_asinhl.c s_atanl.c s_cbrtl.c s_ceill.c s_cosl.c s_cprojl.c \
 	s_csqrtl.c s_exp2l.c s_expl.c s_floorl.c s_fmal.c \
 	s_frexpl.c s_logbl.c s_logl.c s_nanl.c s_nextafterl.c \
 	s_nexttoward.c s_remquol.c s_rintl.c s_scalbnl.c \
@@ -138,11 +138,11 @@ MAN=	acos.3 acosh.3 asin.3 asinh.3 atan.
 	complex.3
 
 MLINKS+=acos.3 acosf.3 acos.3 acosl.3
-MLINKS+=acosh.3 acoshf.3
+MLINKS+=acosh.3 acoshf.3 acosh.3 acoshl.3
 MLINKS+=asin.3 asinf.3 asin.3 asinl.3
-MLINKS+=asinh.3 asinhf.3
+MLINKS+=asinh.3 asinhf.3 asinh.3 asinhl.3
 MLINKS+=atan.3 atanf.3 atan.3 atanl.3
-MLINKS+=atanh.3 atanhf.3
+MLINKS+=atanh.3 atanhf.3 atanh.3 atanhl.3
 MLINKS+=atan2.3 atan2f.3 atan2.3 atan2l.3 \
 	atan2.3 carg.3 atan2.3 cargf.3 atan2.3 cargl.3
 MLINKS+=cacos.3 cacosf.3 cacos.3 cacosh.3 cacos.3 cacoshf.3 \

Modified: head/lib/msun/Symbol.map
==============================================================================
--- head/lib/msun/Symbol.map	Mon Jun 10 06:03:03 2013	(r251598)
+++ head/lib/msun/Symbol.map	Mon Jun 10 06:04:58 2013	(r251599)
@@ -237,6 +237,9 @@ FBSD_1.3 {
 	fegetround;
 	fesetround;
 	fesetenv;
+	acoshl;
+	asinhl;
+	atanhl;
 	cacos;
 	cacosf;
 	cacosh;

Modified: head/lib/msun/man/acosh.3
==============================================================================
--- head/lib/msun/man/acosh.3	Mon Jun 10 06:03:03 2013	(r251598)
+++ head/lib/msun/man/acosh.3	Mon Jun 10 06:04:58 2013	(r251599)
@@ -28,12 +28,13 @@
 .\"     from: @(#)acosh.3	5.2 (Berkeley) 5/6/91
 .\" $FreeBSD$
 .\"
-.Dd January 14, 2005
+.Dd June 9, 2013
 .Dt ACOSH 3
 .Os
 .Sh NAME
 .Nm acosh ,
-.Nm acoshf
+.Nm acoshf ,
+.Nm acoshl
 .Nd inverse hyperbolic cosine functions
 .Sh LIBRARY
 .Lb libm
@@ -43,11 +44,14 @@
 .Fn acosh "double x"
 .Ft float
 .Fn acoshf "float x"
+.Ft long double
+.Fn acoshl "long double x"
 .Sh DESCRIPTION
 The
-.Fn acosh
-and the
-.Fn acoshf
+.Fn acosh ,
+.Fn acoshf ,
+and
+.Fn acoshl
 functions compute the inverse hyperbolic cosine
 of the real
 argument
@@ -55,11 +59,7 @@ argument
 For a discussion of error due to roundoff, see
 .Xr math 3 .
 .Sh RETURN VALUES
-The
-.Fn acosh
-and the
-.Fn acoshf
-functions
+These functions
 return the inverse hyperbolic cosine of
 .Ar x .
 If the argument is less than 1,
@@ -73,6 +73,13 @@ raises an invalid exception and returns 
 .Xr math 3
 .Sh HISTORY
 The
-.Fn acosh
-function appeared in
-.Bx 4.3 .
+.Fn acosh ,
+.Fn acoshf ,
+and
+.Fn acoshl
+functions appeared in
+.Bx 4.3 ,
+.Fx 2.0 ,
+and
+.Fx 10.0 ,
+respectively.

Modified: head/lib/msun/man/asinh.3
==============================================================================
--- head/lib/msun/man/asinh.3	Mon Jun 10 06:03:03 2013	(r251598)
+++ head/lib/msun/man/asinh.3	Mon Jun 10 06:04:58 2013	(r251599)
@@ -28,12 +28,13 @@
 .\"     from: @(#)asinh.3	6.4 (Berkeley) 5/6/91
 .\" $FreeBSD$
 .\"
-.Dd May 6, 1991
+.Dd June 9, 2013
 .Dt ASINH 3
 .Os
 .Sh NAME
 .Nm asinh ,
-.Nm asinhf
+.Nm asinhf ,
+.Nm asinhl
 .Nd inverse hyperbolic sine functions
 .Sh LIBRARY
 .Lb libm
@@ -43,11 +44,14 @@
 .Fn asinh "double x"
 .Ft float
 .Fn asinhf "float x"
+.Ft long double
+.Fn asinhl "long double x"
 .Sh DESCRIPTION
 The
-.Fn asinh
-and the
-.Fn asinhf
+.Fn asinh ,
+.Fn asinhf ,
+and
+.Fn asinhl
 functions compute the inverse hyperbolic sine
 of the real
 argument
@@ -55,11 +59,7 @@ argument
 For a discussion of error due to roundoff, see
 .Xr math 3 .
 .Sh RETURN VALUES
-The
-.Fn asinh
-and the
-.Fn asinhf
-functions
+These functions
 return the inverse hyperbolic sine of
 .Ar x .
 .Sh SEE ALSO
@@ -69,6 +69,13 @@ return the inverse hyperbolic sine of
 .Xr math 3
 .Sh HISTORY
 The
-.Fn asinh
-function appeared in
-.Bx 4.3 .
+.Fn asinh ,
+.Fn asinhf ,
+and
+.Fn asinhl
+functions appeared in
+.Bx 4.3 ,
+.Fx 2.0 ,
+and
+.Fx 10.0 ,
+respectively.

Modified: head/lib/msun/man/atanh.3
==============================================================================
--- head/lib/msun/man/atanh.3	Mon Jun 10 06:03:03 2013	(r251598)
+++ head/lib/msun/man/atanh.3	Mon Jun 10 06:04:58 2013	(r251599)
@@ -28,12 +28,13 @@
 .\"     from: @(#)atanh.3	5.2 (Berkeley) 5/6/91
 .\" $FreeBSD$
 .\"
-.Dd January 14, 2005
+.Dd June 9, 2013
 .Dt ATANH 3
 .Os
 .Sh NAME
 .Nm atanh ,
-.Nm atanhf
+.Nm atanhf ,
+.Nm atanhl
 .Nd inverse hyperbolic tangent functions
 .Sh LIBRARY
 .Lb libm
@@ -43,11 +44,14 @@
 .Fn atanh "double x"
 .Ft float
 .Fn atanhf "float x"
+.Ft long double
+.Fn atanhl "long double x"
 .Sh DESCRIPTION
 The
-.Fn atanh
-and the
-.Fn atanhf
+.Fn atanh ,
+.Fn atanhf ,
+and
+.Fn atanhl
 functions compute the inverse hyperbolic tangent
 of the real
 argument
@@ -55,11 +59,7 @@ argument
 For a discussion of error due to roundoff, see
 .Xr math 3 .
 .Sh RETURN VALUES
-The
-.Fn atanh
-and the
-.Fn atanhf
-functions
+These functions
 return the inverse hyperbolic tangent of
 .Ar x
 if successful.
@@ -76,6 +76,13 @@ If
 .Xr math 3
 .Sh HISTORY
 The
-.Fn atanh
-function appeared in
-.Bx 4.3 .
+.Fn atanh ,
+.Fn atanhf ,
+and
+.Fn atanhl
+functions appeared in
+.Bx 4.3 ,
+.Fx 2.0 ,
+and
+.Fx 10.0 ,
+respectively.

Modified: head/lib/msun/src/e_acosh.c
==============================================================================
--- head/lib/msun/src/e_acosh.c	Mon Jun 10 06:03:03 2013	(r251598)
+++ head/lib/msun/src/e_acosh.c	Mon Jun 10 06:04:58 2013	(r251599)
@@ -29,6 +29,8 @@ __FBSDID("$FreeBSD$");
  *	acosh(NaN) is NaN without signal.
  */
 
+#include <float.h>
+
 #include "math.h"
 #include "math_private.h"
 
@@ -60,3 +62,7 @@ __ieee754_acosh(double x)
 	    return log1p(t+sqrt(2.0*t+t*t));
 	}
 }
+
+#if LDBL_MANT_DIG == 53
+__weak_reference(acosh, acoshl);
+#endif

Copied and modified: head/lib/msun/src/e_acoshl.c (from r251484, head/lib/msun/src/e_acosh.c)
==============================================================================
--- head/lib/msun/src/e_acosh.c	Fri Jun  7 05:18:07 2013	(r251484, copy source)
+++ head/lib/msun/src/e_acoshl.c	Mon Jun 10 06:04:58 2013	(r251599)
@@ -1,3 +1,4 @@
+/* from: FreeBSD: head/lib/msun/src/e_acosh.c 176451 2008-02-22 02:30:36Z das */
 
 /* @(#)e_acosh.c 1.3 95/01/18 */
 /*
@@ -15,48 +16,74 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_acosh(x)
- * Method :
- *	Based on 
- *		acosh(x) = log [ x + sqrt(x*x-1) ]
- *	we have
- *		acosh(x) := log(x)+ln2,	if x is large; else
- *		acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
- *		acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
+/*
+ * See e_acosh.c for complete comments.
  *
- * Special cases:
- *	acosh(x) is NaN with signal if x<1.
- *	acosh(NaN) is NaN without signal.
+ * Converted to long double by David Schultz <das at FreeBSD.ORG> and
+ * Bruce D. Evans.
  */
 
+#include <float.h>
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#include "fpmath.h"
 #include "math.h"
 #include "math_private.h"
 
+/* EXP_LARGE is the threshold above which we use acosh(x) ~= log(2x). */
+#if LDBL_MANT_DIG == 64
+#define	EXP_LARGE	34
+#elif LDBL_MANT_DIG == 113
+#define	EXP_LARGE	58
+#else
+#error "Unsupported long double format"
+#endif
+
+#if LDBL_MAX_EXP != 0x4000
+/* We also require the usual expsign encoding. */
+#error "Unsupported long double format"
+#endif
+
+#define	BIAS	(LDBL_MAX_EXP - 1)
+
 static const double
-one	= 1.0,
-ln2	= 6.93147180559945286227e-01;  /* 0x3FE62E42, 0xFEFA39EF */
+one	= 1.0;
+
+#if LDBL_MANT_DIG == 64
+static const union IEEEl2bits
+u_ln2 =  LD80C(0xb17217f7d1cf79ac, -1, 6.93147180559945309417e-1L);
+#define	ln2	u_ln2.e
+#elif LDBL_MANT_DIG == 113
+static const long double
+ln2 =  6.93147180559945309417232121458176568e-1L;	/* 0x162e42fefa39ef35793c7673007e6.0p-113 */
+#else
+#error "Unsupported long double format"
+#endif
 
-double
-__ieee754_acosh(double x)
+long double
+acoshl(long double x)
 {
-	double t;
-	int32_t hx;
-	u_int32_t lx;
-	EXTRACT_WORDS(hx,lx,x);
-	if(hx<0x3ff00000) {		/* x < 1 */
-	    return (x-x)/(x-x);
-	} else if(hx >=0x41b00000) {	/* x > 2**28 */
-	    if(hx >=0x7ff00000) {	/* x is inf of NaN */
-	        return x+x;
+	long double t;
+	int16_t hx;
+
+	ENTERI();
+	GET_LDBL_EXPSIGN(hx, x);
+	if (hx < 0x3fff) {		/* x < 1, or misnormal */
+	    RETURNI((x-x)/(x-x));
+	} else if (hx >= BIAS + EXP_LARGE) { /* x >= LARGE */
+	    if (hx >= 0x7fff) {		/* x is inf, NaN or misnormal */
+	        RETURNI(x+x);
 	    } else 
-		return __ieee754_log(x)+ln2;	/* acosh(huge)=log(2x) */
-	} else if(((hx-0x3ff00000)|lx)==0) {
-	    return 0.0;			/* acosh(1) = 0 */
-	} else if (hx > 0x40000000) {	/* 2**28 > x > 2 */
+		RETURNI(logl(x)+ln2);	/* acosh(huge)=log(2x), or misnormal */
+	} else if (hx == 0x3fff && x == 1) {
+	    RETURNI(0.0);		/* acosh(1) = 0 */
+	} else if (hx >= 0x4000) {	/* LARGE > x >= 2, or misnormal */
 	    t=x*x;
-	    return __ieee754_log(2.0*x-one/(x+sqrt(t-one)));
+	    RETURNI(logl(2.0*x-one/(x+sqrtl(t-one))));
 	} else {			/* 1<x<2 */
 	    t = x-one;
-	    return log1p(t+sqrt(2.0*t+t*t));
+	    RETURNI(log1pl(t+sqrtl(2.0*t+t*t)));
 	}
 }

Modified: head/lib/msun/src/e_atanh.c
==============================================================================
--- head/lib/msun/src/e_atanh.c	Mon Jun 10 06:03:03 2013	(r251598)
+++ head/lib/msun/src/e_atanh.c	Mon Jun 10 06:04:58 2013	(r251599)
@@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$");
  *
  */
 
+#include <float.h>
+
 #include "math.h"
 #include "math_private.h"
 
@@ -60,3 +62,7 @@ __ieee754_atanh(double x)
 	    t = 0.5*log1p((x+x)/(one-x));
 	if(hx>=0) return t; else return -t;
 }
+
+#if LDBL_MANT_DIG == 53
+__weak_reference(atanh, atanhl);
+#endif

Copied and modified: head/lib/msun/src/e_atanhl.c (from r251484, head/lib/msun/src/e_atanh.c)
==============================================================================
--- head/lib/msun/src/e_atanh.c	Fri Jun  7 05:18:07 2013	(r251484, copy source)
+++ head/lib/msun/src/e_atanhl.c	Mon Jun 10 06:04:58 2013	(r251599)
@@ -1,3 +1,4 @@
+/* from: FreeBSD: head/lib/msun/src/e_atanh.c 176451 2008-02-22 02:30:36Z das */
 
 /* @(#)e_atanh.c 1.3 95/01/18 */
 /*
@@ -15,48 +16,59 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_atanh(x)
- * Method :
- *    1.Reduced x to positive by atanh(-x) = -atanh(x)
- *    2.For x>=0.5
- *                  1              2x                          x
- *	atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
- *                  2             1 - x                      1 - x
- *	
- * 	For x<0.5
- *	atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
- *
- * Special cases:
- *	atanh(x) is NaN if |x| > 1 with signal;
- *	atanh(NaN) is that NaN with no signal;
- *	atanh(+-1) is +-INF with signal.
+/*
+ * See e_atanh.c for complete comments.
  *
+ * Converted to long double by David Schultz <das at FreeBSD.ORG> and
+ * Bruce D. Evans.
  */
 
+#include <float.h>
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#include "fpmath.h"
 #include "math.h"
 #include "math_private.h"
 
+/* EXP_TINY is the threshold below which we use atanh(x) ~= x. */
+#if LDBL_MANT_DIG == 64
+#define	EXP_TINY	-34
+#elif LDBL_MANT_DIG == 113
+#define	EXP_TINY	-58
+#else
+#error "Unsupported long double format"
+#endif
+
+#if LDBL_MAX_EXP != 0x4000
+/* We also require the usual expsign encoding. */
+#error "Unsupported long double format"
+#endif
+
+#define	BIAS	(LDBL_MAX_EXP - 1)
+
 static const double one = 1.0, huge = 1e300;
 static const double zero = 0.0;
 
-double
-__ieee754_atanh(double x)
+long double
+atanhl(long double x)
 {
-	double t;
-	int32_t hx,ix;
-	u_int32_t lx;
-	EXTRACT_WORDS(hx,lx,x);
-	ix = hx&0x7fffffff;
-	if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */
-	    return (x-x)/(x-x);
-	if(ix==0x3ff00000) 
-	    return x/zero;
-	if(ix<0x3e300000&&(huge+x)>zero) return x;	/* x<2**-28 */
-	SET_HIGH_WORD(x,ix);
-	if(ix<0x3fe00000) {		/* x < 0.5 */
+	long double t;
+	uint16_t hx, ix;
+
+	ENTERI();
+	GET_LDBL_EXPSIGN(hx, x);
+	ix = hx & 0x7fff;
+	if (ix >= 0x3fff)		/* |x| >= 1, or NaN or misnormal */
+	    RETURNI(fabsl(x) == 1 ? x / zero : (x - x) / (x - x));
+	if (ix < BIAS + EXP_TINY && (huge + x) > zero)
+	    RETURNI(x);			/* x is tiny */
+	SET_LDBL_EXPSIGN(x, ix);
+	if (ix < 0x3ffe) {		/* |x| < 0.5, or misnormal */
 	    t = x+x;
-	    t = 0.5*log1p(t+t*x/(one-x));
+	    t = 0.5*log1pl(t+t*x/(one-x));
 	} else 
-	    t = 0.5*log1p((x+x)/(one-x));
-	if(hx>=0) return t; else return -t;
+	    t = 0.5*log1pl((x+x)/(one-x));
+	RETURNI((hx & 0x8000) == 0 ? t : -t);
 }

Modified: head/lib/msun/src/math.h
==============================================================================
--- head/lib/msun/src/math.h	Mon Jun 10 06:03:03 2013	(r251598)
+++ head/lib/msun/src/math.h	Mon Jun 10 06:04:58 2013	(r251599)
@@ -395,9 +395,12 @@ float	significandf(float);
  * long double versions of ISO/POSIX math functions
  */
 #if __ISO_C_VISIBLE >= 1999
+long double	acoshl(long double);
 long double	acosl(long double);
+long double	asinhl(long double);
 long double	asinl(long double);
 long double	atan2l(long double, long double);
+long double	atanhl(long double);
 long double	atanl(long double);
 long double	cbrtl(long double);
 long double	ceill(long double);
@@ -461,9 +464,6 @@ __END_DECLS
  */
 __BEGIN_DECLS
 
-long double	acoshl(long double);
-long double	asinhl(long double);
-long double	atanhl(long double);
 long double	coshl(long double);
 long double	erfcl(long double);
 long double	erfl(long double);

Modified: head/lib/msun/src/s_asinh.c
==============================================================================
--- head/lib/msun/src/s_asinh.c	Mon Jun 10 06:03:03 2013	(r251598)
+++ head/lib/msun/src/s_asinh.c	Mon Jun 10 06:04:58 2013	(r251599)
@@ -24,6 +24,8 @@ __FBSDID("$FreeBSD$");
  *		 := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
  */
 
+#include <float.h>
+
 #include "math.h"
 #include "math_private.h"
 
@@ -54,3 +56,7 @@ asinh(double x)
 	}
 	if(hx>0) return w; else return -w;
 }
+
+#if LDBL_MANT_DIG == 53
+__weak_reference(asinh, asinhl);
+#endif

Copied and modified: head/lib/msun/src/s_asinhl.c (from r251484, head/lib/msun/src/s_asinh.c)
==============================================================================
--- head/lib/msun/src/s_asinh.c	Fri Jun  7 05:18:07 2013	(r251484, copy source)
+++ head/lib/msun/src/s_asinhl.c	Mon Jun 10 06:04:58 2013	(r251599)
@@ -1,3 +1,5 @@
+/* from: FreeBSD: head/lib/msun/src/e_acosh.c 176451 2008-02-22 02:30:36Z das */
+
 /* @(#)s_asinh.c 5.1 93/09/24 */
 /*
  * ====================================================
@@ -13,44 +15,77 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* asinh(x)
- * Method :
- *	Based on
- *		asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
- *	we have
- *	asinh(x) := x  if  1+x*x=1,
- *		 := sign(x)*(log(x)+ln2)) for large |x|, else
- *		 := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
- *		 := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
+/*
+ * See s_asinh.c for complete comments.
+ *
+ * Converted to long double by David Schultz <das at FreeBSD.ORG> and
+ * Bruce D. Evans.
  */
 
+#include <float.h>
+#ifdef __i386__
+#include <ieeefp.h>
+#endif
+
+#include "fpmath.h"
 #include "math.h"
 #include "math_private.h"
 
+/* EXP_LARGE is the threshold above which we use asinh(x) ~= log(2x). */
+/* EXP_TINY is the threshold below which we use asinh(x) ~= x. */
+#if LDBL_MANT_DIG == 64
+#define	EXP_LARGE	34
+#define	EXP_TINY	-34
+#elif LDBL_MANT_DIG == 113
+#define	EXP_LARGE	58
+#define	EXP_TINY	-58
+#else
+#error "Unsupported long double format"
+#endif
+
+#if LDBL_MAX_EXP != 0x4000
+/* We also require the usual expsign encoding. */
+#error "Unsupported long double format"
+#endif
+
+#define	BIAS	(LDBL_MAX_EXP - 1)
+
 static const double
 one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
-ln2 =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
 huge=  1.00000000000000000000e+300;
 
-double
-asinh(double x)
+#if LDBL_MANT_DIG == 64
+static const union IEEEl2bits
+u_ln2 =  LD80C(0xb17217f7d1cf79ac, -1, 6.93147180559945309417e-1L);
+#define	ln2	u_ln2.e
+#elif LDBL_MANT_DIG == 113
+static const long double
+ln2 =  6.93147180559945309417232121458176568e-1L;	/* 0x162e42fefa39ef35793c7673007e6.0p-113 */
+#else
+#error "Unsupported long double format"
+#endif
+
+long double
+asinhl(long double x)
 {
-	double t,w;
-	int32_t hx,ix;
-	GET_HIGH_WORD(hx,x);
-	ix = hx&0x7fffffff;
-	if(ix>=0x7ff00000) return x+x;	/* x is inf or NaN */
-	if(ix< 0x3e300000) {	/* |x|<2**-28 */
-	    if(huge+x>one) return x;	/* return x inexact except 0 */
+	long double t, w;
+	uint16_t hx, ix;
+
+	ENTERI();
+	GET_LDBL_EXPSIGN(hx, x);
+	ix = hx & 0x7fff;
+	if (ix >= 0x7fff) RETURNI(x+x);	/* x is inf, NaN or misnormal */
+	if (ix < BIAS + EXP_TINY) {	/* |x| < TINY, or misnormal */
+	    if (huge + x > one) RETURNI(x);	/* return x inexact except 0 */
 	}
-	if(ix>0x41b00000) {	/* |x| > 2**28 */
-	    w = __ieee754_log(fabs(x))+ln2;
-	} else if (ix>0x40000000) {	/* 2**28 > |x| > 2.0 */
-	    t = fabs(x);
-	    w = __ieee754_log(2.0*t+one/(__ieee754_sqrt(x*x+one)+t));
-	} else {		/* 2.0 > |x| > 2**-28 */
+	if (ix >= BIAS + EXP_LARGE) {	/* |x| >= LARGE, or misnormal */
+	    w = logl(fabsl(x))+ln2;
+	} else if (ix >= 0x4000) {	/* LARGE > |x| >= 2.0, or misnormal */
+	    t = fabsl(x);
+	    w = logl(2.0*t+one/(sqrtl(x*x+one)+t));
+	} else {		/* 2.0 > |x| >= TINY, or misnormal */
 	    t = x*x;
-	    w =log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t)));
+	    w =log1pl(fabsl(x)+t/(one+sqrtl(one+t)));
 	}
-	if(hx>0) return w; else return -w;
+	RETURNI((hx & 0x8000) == 0 ? w : -w);
 }


More information about the svn-src-all mailing list