summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2013-06-10 06:04:58 +0000
committerdas <das@FreeBSD.org>2013-06-10 06:04:58 +0000
commit4e8602cd3988d7feb832032e4eb9c5a560af08f0 (patch)
tree86fabb2acfe36058b468630da526ea699b62d9b8
parentdc9bd08e99b5ce900fa2f3d1c8cd7b3e36c029e2 (diff)
downloadFreeBSD-src-4e8602cd3988d7feb832032e4eb9c5a560af08f0.zip
FreeBSD-src-4e8602cd3988d7feb832032e4eb9c5a560af08f0.tar.gz
Add implementations of acoshl(), asinhl(), and atanhl(). This is a
merge of the work done by bde and myself.
-rw-r--r--lib/msun/Makefile12
-rw-r--r--lib/msun/Symbol.map3
-rw-r--r--lib/msun/man/acosh.333
-rw-r--r--lib/msun/man/asinh.333
-rw-r--r--lib/msun/man/atanh.333
-rw-r--r--lib/msun/src/e_acosh.c6
-rw-r--r--lib/msun/src/e_acoshl.c89
-rw-r--r--lib/msun/src/e_atanh.c6
-rw-r--r--lib/msun/src/e_atanhl.c74
-rw-r--r--lib/msun/src/math.h6
-rw-r--r--lib/msun/src/s_asinh.c6
-rw-r--r--lib/msun/src/s_asinhl.c91
12 files changed, 344 insertions, 48 deletions
diff --git a/lib/msun/Makefile b/lib/msun/Makefile
index 43e4b0b..14db97e 100644
--- a/lib/msun/Makefile
+++ b/lib/msun/Makefile
@@ -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.3 atan2.3 atanh.3 \
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 \
diff --git a/lib/msun/Symbol.map b/lib/msun/Symbol.map
index 045ac92..f244af4 100644
--- a/lib/msun/Symbol.map
+++ b/lib/msun/Symbol.map
@@ -237,6 +237,9 @@ FBSD_1.3 {
fegetround;
fesetround;
fesetenv;
+ acoshl;
+ asinhl;
+ atanhl;
cacos;
cacosf;
cacosh;
diff --git a/lib/msun/man/acosh.3 b/lib/msun/man/acosh.3
index cd04bb7..b32c2ea 100644
--- a/lib/msun/man/acosh.3
+++ b/lib/msun/man/acosh.3
@@ -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 an \*(Na.
.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.
diff --git a/lib/msun/man/asinh.3 b/lib/msun/man/asinh.3
index 6dba217..bab8da6 100644
--- a/lib/msun/man/asinh.3
+++ b/lib/msun/man/asinh.3
@@ -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.
diff --git a/lib/msun/man/atanh.3 b/lib/msun/man/atanh.3
index 0638a1f..7763c46 100644
--- a/lib/msun/man/atanh.3
+++ b/lib/msun/man/atanh.3
@@ -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.
diff --git a/lib/msun/src/e_acosh.c b/lib/msun/src/e_acosh.c
index a0cc6cb..358c8bd 100644
--- a/lib/msun/src/e_acosh.c
+++ b/lib/msun/src/e_acosh.c
@@ -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
diff --git a/lib/msun/src/e_acoshl.c b/lib/msun/src/e_acoshl.c
new file mode 100644
index 0000000..b9f3aed
--- /dev/null
+++ b/lib/msun/src/e_acoshl.c
@@ -0,0 +1,89 @@
+/* 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 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * See e_acosh.c for complete comments.
+ *
+ * Converted to long double by David Schultz <das@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;
+
+#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
+acoshl(long double 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
+ 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;
+ RETURNI(logl(2.0*x-one/(x+sqrtl(t-one))));
+ } else { /* 1<x<2 */
+ t = x-one;
+ RETURNI(log1pl(t+sqrtl(2.0*t+t*t)));
+ }
+}
diff --git a/lib/msun/src/e_atanh.c b/lib/msun/src/e_atanh.c
index ab8a2e1..422ff26 100644
--- a/lib/msun/src/e_atanh.c
+++ b/lib/msun/src/e_atanh.c
@@ -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
diff --git a/lib/msun/src/e_atanhl.c b/lib/msun/src/e_atanhl.c
new file mode 100644
index 0000000..11d56ea
--- /dev/null
+++ b/lib/msun/src/e_atanhl.c
@@ -0,0 +1,74 @@
+/* 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 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * See e_atanh.c for complete comments.
+ *
+ * Converted to long double by David Schultz <das@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;
+
+long double
+atanhl(long double x)
+{
+ 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*log1pl(t+t*x/(one-x));
+ } else
+ t = 0.5*log1pl((x+x)/(one-x));
+ RETURNI((hx & 0x8000) == 0 ? t : -t);
+}
diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h
index 8d0d478..d831f15 100644
--- a/lib/msun/src/math.h
+++ b/lib/msun/src/math.h
@@ -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);
diff --git a/lib/msun/src/s_asinh.c b/lib/msun/src/s_asinh.c
index f3fdf74..cbb3d46 100644
--- a/lib/msun/src/s_asinh.c
+++ b/lib/msun/src/s_asinh.c
@@ -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
diff --git a/lib/msun/src/s_asinhl.c b/lib/msun/src/s_asinhl.c
new file mode 100644
index 0000000..ba28f59
--- /dev/null
+++ b/lib/msun/src/s_asinhl.c
@@ -0,0 +1,91 @@
+/* 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 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * See s_asinh.c for complete comments.
+ *
+ * Converted to long double by David Schultz <das@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 */
+huge= 1.00000000000000000000e+300;
+
+#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)
+{
+ 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 >= 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 =log1pl(fabsl(x)+t/(one+sqrtl(one+t)));
+ }
+ RETURNI((hx & 0x8000) == 0 ? w : -w);
+}
OpenPOWER on IntegriCloud