aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/libm-ieee754
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-01-01 15:28:18 +0000
committerUlrich Drepper <drepper@redhat.com>1997-01-01 15:28:18 +0000
commit6bc31da01b1271826c8feefb5f0efdf22d64061c (patch)
tree14aacf79623cde45cda8b839a225609eb4873540 /sysdeps/libm-ieee754
parentea971c878fda0a93a568732ca5a8a36524f77ec2 (diff)
downloadglibc-6bc31da01b1271826c8feefb5f0efdf22d64061c.tar
glibc-6bc31da01b1271826c8feefb5f0efdf22d64061c.tar.gz
glibc-6bc31da01b1271826c8feefb5f0efdf22d64061c.tar.bz2
glibc-6bc31da01b1271826c8feefb5f0efdf22d64061c.zip
update from main archive 970101cvs/libc-970102
Wed Jan 1 15:15:00 1997 Ulrich Drepper <drepper@cygnus.com> * libio/Makefile (routines): Add fcloseall. * libio/fcloseall.c: New file. * libio/stdio.h [__USE_GNU]: Add prototype for fcloseall. * libio/iofclose.c: Don't close all streams when argument is NULL. * stdio/Makefile (routines): Add fcloseall. * stdio/fcloseall.c: New file. * stdio/stdio.h [__USE_GNU]: Add prototype for fcloseall. * stdio/fclose.c: Don't close all streams when argument is NULL. * manual/stdio.texi: Document fcloseall. * sysdeps/generic/abort.c: Call __fcloseall instead of fclose with NULL argument. * socket/sys/un.h (SUN_LEN): Add cast. * sunrpc/auth_unix.c (authunix_create): Change parameter types of uid, gid, and aup_gids to uid_t and gid_t respectively. (authunix_create_default): Likewise. (authunix_refresh): Correct cast for aup_gids assignment. * sunrpc/rpc/auth.h (authunix_create): Correct types in declaration. * sunrpc/rpc/auth_unix.h (struct authunix_parms): Correct field types to uid_t and gid_t respectively. (struct short_hand_verf): Likewise. Reported by Andreas Schwab. * sysdeps/ieee754/Makefile: New file. Make sure ieee754.h gets installed. * sysdeps/ieee754/ieee754.h: Protect against multiple inclusion and use in C++ programs. * sysdeps/libm-i387/e_pow.S: New file. Optimized ix87 assembler version of pow() function. * sysdeps/libm-i387/e_powf.S: New file. Float version. * sysdeps/libm-i387/e_powl.S: New file. Long double version. * sysdeps/libm-i387/s_expm1.S: New file. Optimized ix87 assembler version of expm1() function. * sysdeps/libm-i387/s_expm1f.S: New file. Float version. * sysdeps/libm-i387/s_expm1l.S: New file. Long double version. * sysdeps/libm-i387/e_exp.S: Optimize handling of +-Inf. Better handling of computation stack from current NetBSD sources. * sysdeps/libm-i387/e_expf.S: Likewise. * sysdeps/libm-i387/e_expl.S: Likewise. * sysdeps/libm-i387/e_log.S: Use fstp instead of fincstp. * sysdeps/libm-i387/e_logf.S: Likewise. * sysdeps/libm-i387/e_logl.S: Likewise. * sysdeps/libm-i387/e_log10.S: Likewise. * sysdeps/libm-i387/e_log10f.S: Likewise. * sysdeps/libm-i387/e_log10l.S: Likewise. * sysdeps/libm-i387/s_asinh.S: Likewise. * sysdeps/libm-i387/s_asinhf.S: Likewise. * sysdeps/libm-i387/s_asinhl.S: Likewise. * sysdeps/libm-i387/s_significandl.S: Likewise. * sysdeps/libm-i387/s_ceil.S: Don't create stack frame. Modify stack pointer directly. Use 32 bit instead of 16 bit operations. * sysdeps/libm-i387/s_ceilf.S: Likewise. * sysdeps/libm-i387/s_ceill.S: Likewise. * sysdeps/libm-i387/s_floor.S: Likewise. * sysdeps/libm-i387/s_floorf.S: Likewise. * sysdeps/libm-i387/s_floorl.S: Likewise. * sysdeps/libm-ieee754/e_coshf.c (huge): Don't declare volatile. * sysdeps/libm-ieee754/e_expf.c: Likewise. * sysdeps/libm-ieee754/e_powf.c: Likewise. From current NetBSD sources. * sysdeps/libm-ieee754/e_hypot.c (__ieee754_hypot): Don't initialize `a' and `b' in definition. * sysdeps/libm-ieee754/e_hypotf.c: Likewise. * sysdeps/libm-ieee754/e_hypotl.c: New file. Long double implementation. * sysdeps/libm-ieee754/e_sinhl.c: New file. Long double implementation. * sysdeps/stub/e_hypotl.c: Removed. We have a real version now. * sysdeps/stub/e_sinhl.c: Removed. * sysdeps/posix/sigpause.c (__sigpause): Use sigdelset instead of sigaddset. Reported by Andreas Schwab. (__default_sigpause): New function. Call __sigpause as BSD version. Make this the default function by providing alias sigpause. * sysdeps/stub/sigpause.c (__default_sigpause): New funciton. Simply fail. Provide alias sigpause. Wed Jan 1 12:34:54 1997 Ulrich Drepper <drepper@cygnus.com> * po/es.po: Update for glibc-1.98. * po/fr.po: Likewise. * po/sv.po: New file. Swedish translation. Wed Jan 1 12:18:07 1997 MacGyver <macgyver@tos.net> * values.h: Fix typos: use SHRT_MAX but SHORT_MAX and SHRT_MIN but SHORT_MIN. Tue Dec 24 23:10:21 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * Makefile: Replace `stubs.h' by `gnu/stubs.h'. * features.h: Include <gnu/stubs.h> instead of <stubs.h>. Tue Dec 24 22:16:55 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * Makefile (subdirs): Move `elf' last so that librtld.so isn't relinked in the `make others' pass if an add-on adds something to libc. Mon Dec 23 21:23:16 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/m68k/abort-instr.h: New File. Mon Dec 23 21:16:38 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/m68k/Makefile ($(subdir)=elf): Define CFLAGS-rtld.c to prevent warning. Mon Dec 23 21:14:22 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * resolv/Makefile (subdirs-dirs): Define. Mon Dec 23 20:56:49 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/gnu/utmpbits.h (struct utmp): Fix padding. Mon Dec 30 11:05:11 1996 Ulrich Drepper <drepper@cygnus.com> Update from ADO tzcode1996o. * time/difftime.c: De-ANSI-declfy. Simplify computation of hibit according to ADO version. * time/zic.c: Correct typo is message. Update from ADO tzdata1996n. * time/asia: Updated. * time/australasia: Likewise. * time/europe: Likewise. * time/northamerica: Likewise. * time/southamerica: Likewise.
Diffstat (limited to 'sysdeps/libm-ieee754')
-rw-r--r--sysdeps/libm-ieee754/e_coshf.c10
-rw-r--r--sysdeps/libm-ieee754/e_expf.c12
-rw-r--r--sysdeps/libm-ieee754/e_hypot.c24
-rw-r--r--sysdeps/libm-ieee754/e_hypotf.c6
-rw-r--r--sysdeps/libm-ieee754/e_hypotl.c133
-rw-r--r--sysdeps/libm-ieee754/e_powf.c4
-rw-r--r--sysdeps/libm-ieee754/e_sinhl.c91
7 files changed, 252 insertions, 28 deletions
diff --git a/sysdeps/libm-ieee754/e_coshf.c b/sysdeps/libm-ieee754/e_coshf.c
index e6f4ed6f37..223fbeea20 100644
--- a/sysdeps/libm-ieee754/e_coshf.c
+++ b/sysdeps/libm-ieee754/e_coshf.c
@@ -8,20 +8,20 @@
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
+ * software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: e_coshf.c,v 1.5 1995/05/10 20:45:01 jtc Exp $";
+static char rcsid[] = "$NetBSD: e_coshf.c,v 1.6 1996/04/08 15:43:41 phil Exp $";
#endif
#include "math.h"
#include "math_private.h"
#ifdef __STDC__
-static const volatile float huge = 1.0e30;
+static const float huge = 1.0e30;
static const float one = 1.0, half=0.5;
#else
static float one = 1.0, half=0.5, huge = 1.0e30;
@@ -33,7 +33,7 @@ static float one = 1.0, half=0.5, huge = 1.0e30;
float __ieee754_coshf(x)
float x;
#endif
-{
+{
float t,w;
int32_t ix;
@@ -41,7 +41,7 @@ static float one = 1.0, half=0.5, huge = 1.0e30;
ix &= 0x7fffffff;
/* x is INF or NaN */
- if(ix>=0x7f800000) return x*x;
+ if(ix>=0x7f800000) return x*x;
/* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
if(ix<0x3eb17218) {
diff --git a/sysdeps/libm-ieee754/e_expf.c b/sysdeps/libm-ieee754/e_expf.c
index 80af17918f..fbf2691bf9 100644
--- a/sysdeps/libm-ieee754/e_expf.c
+++ b/sysdeps/libm-ieee754/e_expf.c
@@ -8,19 +8,19 @@
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
+ * software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: e_expf.c,v 1.5 1995/05/10 20:45:05 jtc Exp $";
+static char rcsid[] = "$NetBSD: e_expf.c,v 1.6 1996/04/08 15:43:43 phil Exp $";
#endif
#include "math.h"
#include "math_private.h"
-static const volatile float huge = 1.0e+30;
+static const float huge = 1.0e+30;
#ifdef __STDC__
static const float
@@ -69,7 +69,7 @@ P5 = 4.1381369442e-08; /* 0x3331bb4c */
}
/* argument reduction */
- if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
+ if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
if(hx < 0x3F851592) { /* and |x| < 1.5 ln2 */
hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
} else {
@@ -79,7 +79,7 @@ P5 = 4.1381369442e-08; /* 0x3331bb4c */
lo = t*ln2LO[0];
}
x = hi - lo;
- }
+ }
else if(hx < 0x31800000) { /* when |x|<2**-28 */
if(huge+x>one) return one+x;/* trigger inexact */
}
@@ -88,7 +88,7 @@ P5 = 4.1381369442e-08; /* 0x3331bb4c */
/* x is now in primary range */
t = x*x;
c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
- if(k==0) return one-((x*c)/(c-(float)2.0)-x);
+ if(k==0) return one-((x*c)/(c-(float)2.0)-x);
else y = one-((lo-(x*c)/((float)2.0-c))-hi);
if(k >= -125) {
u_int32_t hy;
diff --git a/sysdeps/libm-ieee754/e_hypot.c b/sysdeps/libm-ieee754/e_hypot.c
index 24c8ae452f..76a77ec33a 100644
--- a/sysdeps/libm-ieee754/e_hypot.c
+++ b/sysdeps/libm-ieee754/e_hypot.c
@@ -5,7 +5,7 @@
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
+ * software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
@@ -16,12 +16,12 @@ static char rcsid[] = "$NetBSD: e_hypot.c,v 1.9 1995/05/12 04:57:27 jtc Exp $";
/* __ieee754_hypot(x,y)
*
- * Method :
- * If (assume round-to-nearest) z=x*x+y*y
- * has error less than sqrt(2)/2 ulp, than
+ * Method :
+ * If (assume round-to-nearest) z=x*x+y*y
+ * has error less than sqrt(2)/2 ulp, than
* sqrt(z) has error less than 1 ulp (exercise).
*
- * So, compute sqrt(x*x+y*y) with some care as
+ * So, compute sqrt(x*x+y*y) with some care as
* follows to get the error below 1 ulp:
*
* Assume x>y>0;
@@ -31,10 +31,10 @@ static char rcsid[] = "$NetBSD: e_hypot.c,v 1.9 1995/05/12 04:57:27 jtc Exp $";
* where x1 = x with lower 32 bits cleared, x2 = x-x1; else
* 2. if x <= 2y use
* t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
- * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
+ * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
* y1= y with lower 32 bits chopped, y2 = y-y1.
- *
- * NOTE: scaling may be necessary if some argument is too
+ *
+ * NOTE: scaling may be necessary if some argument is too
* large or too tiny
*
* Special cases:
@@ -42,8 +42,8 @@ static char rcsid[] = "$NetBSD: e_hypot.c,v 1.9 1995/05/12 04:57:27 jtc Exp $";
* hypot(x,y) is NAN if x or y is NAN.
*
* Accuracy:
- * hypot(x,y) returns sqrt(x^2+y^2) with error less
- * than 1 ulps (units in the last place)
+ * hypot(x,y) returns sqrt(x^2+y^2) with error less
+ * than 1 ulps (units in the last place)
*/
#include "math.h"
@@ -56,7 +56,7 @@ static char rcsid[] = "$NetBSD: e_hypot.c,v 1.9 1995/05/12 04:57:27 jtc Exp $";
double x, y;
#endif
{
- double a=x,b=y,t1,t2,y1,y2,w;
+ double a,b,t1,t2,y1,y2,w;
int32_t j,k,ha,hb;
GET_HIGH_WORD(ha,x);
@@ -84,7 +84,7 @@ static char rcsid[] = "$NetBSD: e_hypot.c,v 1.9 1995/05/12 04:57:27 jtc Exp $";
SET_HIGH_WORD(b,hb);
}
if(hb < 0x20b00000) { /* b < 2**-500 */
- if(hb <= 0x000fffff) { /* subnormal b or 0 */
+ if(hb <= 0x000fffff) { /* subnormal b or 0 */
u_int32_t low;
GET_LOW_WORD(low,b);
if((hb|low)==0) return a;
diff --git a/sysdeps/libm-ieee754/e_hypotf.c b/sysdeps/libm-ieee754/e_hypotf.c
index 434cf94e8d..d6b1520cb8 100644
--- a/sysdeps/libm-ieee754/e_hypotf.c
+++ b/sysdeps/libm-ieee754/e_hypotf.c
@@ -8,7 +8,7 @@
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
+ * software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
@@ -27,7 +27,7 @@ static char rcsid[] = "$NetBSD: e_hypotf.c,v 1.5 1995/05/12 04:57:30 jtc Exp $";
float x, y;
#endif
{
- float a=x,b=y,t1,t2,y1,y2,w;
+ float a,b,t1,t2,y1,y2,w;
int32_t j,k,ha,hb;
GET_FLOAT_WORD(ha,x);
@@ -52,7 +52,7 @@ static char rcsid[] = "$NetBSD: e_hypotf.c,v 1.5 1995/05/12 04:57:30 jtc Exp $";
SET_FLOAT_WORD(b,hb);
}
if(hb < 0x26800000) { /* b < 2**-50 */
- if(hb <= 0x007fffff) { /* subnormal b or 0 */
+ if(hb <= 0x007fffff) { /* subnormal b or 0 */
if(hb==0) return a;
SET_FLOAT_WORD(t1,0x3f000000); /* t1=2^126 */
b *= t1;
diff --git a/sysdeps/libm-ieee754/e_hypotl.c b/sysdeps/libm-ieee754/e_hypotl.c
new file mode 100644
index 0000000000..1a40c556dc
--- /dev/null
+++ b/sysdeps/libm-ieee754/e_hypotl.c
@@ -0,0 +1,133 @@
+/* e_hypotl.c -- long double version of e_hypot.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* __ieee754_hypotl(x,y)
+ *
+ * Method :
+ * If (assume round-to-nearest) z=x*x+y*y
+ * has error less than sqrt(2)/2 ulp, than
+ * sqrt(z) has error less than 1 ulp (exercise).
+ *
+ * So, compute sqrt(x*x+y*y) with some care as
+ * follows to get the error below 1 ulp:
+ *
+ * Assume x>y>0;
+ * (if possible, set rounding to round-to-nearest)
+ * 1. if x > 2y use
+ * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
+ * where x1 = x with lower 32 bits cleared, x2 = x-x1; else
+ * 2. if x <= 2y use
+ * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
+ * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1,
+ * y1= y with lower 32 bits chopped, y2 = y-y1.
+ *
+ * NOTE: scaling may be necessary if some argument is too
+ * large or too tiny
+ *
+ * Special cases:
+ * hypot(x,y) is INF if x or y is +INF or -INF; else
+ * hypot(x,y) is NAN if x or y is NAN.
+ *
+ * Accuracy:
+ * hypot(x,y) returns sqrt(x^2+y^2) with error less
+ * than 1 ulps (units in the last place)
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+ long double __ieee754_hypotl(long double x, long double y)
+#else
+ long double __ieee754_hypotl(x,y)
+ long double x, y;
+#endif
+{
+ long double a,b,t1,t2,y1,y2,w;
+ u_int32_t j,k,ea,eb;
+
+ GET_LDOUBLE_EXP(ea,x);
+ ea &= 0x7fff;
+ GET_LDOUBLE_EXP(eb,y);
+ eb &= 0x7fff;
+ if(eb > ea) {a=y;b=x;j=ea; ea=eb;eb=j;} else {a=x;b=y;}
+ SET_LDOUBLE_EXP(a,ea); /* a <- |a| */
+ SET_LDOUBLE_EXP(b,eb); /* b <- |b| */
+ if((ea-eb)>0x46) {return a+b;} /* x/y > 2**70 */
+ k=0;
+ if(ea > 0x5f3f) { /* a>2**8000 */
+ if(ea == 0x7fff) { /* Inf or NaN */
+ u_int32_t exp,high,low;
+ w = a+b; /* for sNaN */
+ GET_LDOUBLE_WORDS(exp,high,low,a);
+ if(((high&0x7fffffff)|low)==0) w = a;
+ GET_LDOUBLE_WORDS(exp,high,low,b);
+ if(((eb^0x7fff)|(high&0x7fffffff)|low)==0) w = b;
+ return w;
+ }
+ /* scale a and b by 2**-9600 */
+ ea -= 0x2580; eb -= 0x2580; k += 9600;
+ SET_LDOUBLE_EXP(a,ea);
+ SET_LDOUBLE_EXP(b,eb);
+ }
+ if(eb < 0x20bf) { /* b < 2**-8000 */
+ if(eb == 0) { /* subnormal b or 0 */
+ u_int32_t exp,high,low;
+ GET_LDOUBLE_WORDS(exp,high,low,b);
+ if((high|low)==0) return a;
+ SET_LDOUBLE_WORDS(t1, 0x7ffd, 0, 0); /* t1=2^16382 */
+ b *= t1;
+ a *= t1;
+ k -= 16382;
+ } else { /* scale a and b by 2^9600 */
+ ea += 0x2580; /* a *= 2^9600 */
+ eb += 0x2580; /* b *= 2^9600 */
+ k -= 9600;
+ SET_LDOUBLE_EXP(a,ea);
+ SET_LDOUBLE_EXP(b,eb);
+ }
+ }
+ /* medium size a and b */
+ w = a-b;
+ if (w>b) {
+ u_int32_t high;
+ GET_LDOUBLE_MSW(high,a);
+ SET_LDOUBLE_WORDS(t1,ea,high,0);
+ t2 = a-t1;
+ w = __ieee754_sqrtl(t1*t1-(b*(-b)-t2*(a+t1)));
+ } else {
+ u_int32_t high;
+ GET_LDOUBLE_MSW(high,b);
+ a = a+a;
+ SET_LDOUBLE_WORDS(y1,eb,high,0);
+ y2 = b - y1;
+ GET_LDOUBLE_MSW(high,a);
+ SET_LDOUBLE_WORDS(t1,ea+1,high,0);
+ t2 = a - t1;
+ w = __ieee754_sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+ }
+ if(k!=0) {
+ u_int32_t exp;
+ t1 = 1.0;
+ GET_LDOUBLE_EXP(exp,t1);
+ SET_LDOUBLE_EXP(t1,exp+k);
+ return t1*w;
+ } else return w;
+}
diff --git a/sysdeps/libm-ieee754/e_powf.c b/sysdeps/libm-ieee754/e_powf.c
index 1358555128..4798340c84 100644
--- a/sysdeps/libm-ieee754/e_powf.c
+++ b/sysdeps/libm-ieee754/e_powf.c
@@ -14,13 +14,13 @@
*/
#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: e_powf.c,v 1.6 1995/05/12 04:57:35 jtc Exp $";
+static char rcsid[] = "$NetBSD: e_powf.c,v 1.7 1996/04/08 15:43:44 phil Exp $";
#endif
#include "math.h"
#include "math_private.h"
-static const volatile float huge = 1.0e+30, tiny = 1.0e-30;
+static const float huge = 1.0e+30, tiny = 1.0e-30;
#ifdef __STDC__
static const float
diff --git a/sysdeps/libm-ieee754/e_sinhl.c b/sysdeps/libm-ieee754/e_sinhl.c
new file mode 100644
index 0000000000..2d98562f94
--- /dev/null
+++ b/sysdeps/libm-ieee754/e_sinhl.c
@@ -0,0 +1,91 @@
+/* e_asinhl.c -- long double version of e_asinh.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * 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.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* __ieee754_sinhl(x)
+ * Method :
+ * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+ * 1. Replace x by |x| (sinhl(-x) = -sinhl(x)).
+ * 2.
+ * E + E/(E+1)
+ * 0 <= x <= 25 : sinhl(x) := --------------, E=expm1l(x)
+ * 2
+ *
+ * 25 <= x <= lnovft : sinhl(x) := expl(x)/2
+ * lnovft <= x <= ln2ovft: sinhl(x) := expl(x/2)/2 * expl(x/2)
+ * ln2ovft < x : sinhl(x) := x*shuge (overflow)
+ *
+ * Special cases:
+ * sinhl(x) is |x| if x is +INF, -INF, or NaN.
+ * only sinhl(0)=0 is exact for finite x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+static const long double one = 1.0, shuge = 1.0e4931L;
+#else
+static long double one = 1.0, shuge = 1.0e4931L;
+#endif
+
+#ifdef __STDC__
+ long double __ieee754_sinhl(long double x)
+#else
+ long double __ieee754_sinhl(x)
+ long double x;
+#endif
+{
+ long double t,w,h;
+ u_int32_t jx,ix,i0,i1;
+
+ /* Words of |x|. */
+ GET_LDOUBLE_WORDS(jx,i0,i1,x);
+ ix = jx&0x7fff;
+
+ /* x is INF or NaN */
+ if(ix==0x7fff) return x+x;
+
+ h = 0.5;
+ if (jx<0) h = -h;
+ /* |x| in [0,25], return sign(x)*0.5*(E+E/(E+1))) */
+ if (ix < 0x4003 || (ix == 0x4003 && i0 <= 0xc8000000)) { /* |x|<25 */
+ if (ix<0x3fe3) /* |x|<2**-28 */
+ if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
+ t = __expm1l(fabsl(x));
+ if(ix<0x3fff) return h*(2.0*t-t*t/(t+one));
+ return h*(t+t/(t+one));
+ }
+
+ /* |x| in [25, log(maxdouble)] return 0.5*exp(|x|) */
+ if (ix < 0x400c || (ix == 0x400c && i0 < 0xb17217f7))
+ return h*__ieee754_expl(fabsl(x));
+
+ /* |x| in [log(maxdouble), overflowthresold] */
+ if (ix<0x400c || (ix == 0x400c && (i0 < 0xb174ddc0
+ || (i0 == 0xb174ddc0
+ && i1 <= 0x31aec0ea)))) {
+ w = __ieee754_expl(0.5*fabsl(x));
+ t = h*w;
+ return t*w;
+ }
+
+ /* |x| > overflowthresold, sinhl(x) overflow */
+ return x*shuge;
+}