diff options
Diffstat (limited to 'sysdeps/ieee754/ldbl-128ibm')
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/e_acoshl.c | 2 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/e_expl.c | 4 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/e_logl.c | 13 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/math_ldbl.h | 10 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/w_expl.c | 26 |
5 files changed, 44 insertions, 11 deletions
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c b/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c index 117bd0f052..abc78a35bd 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c @@ -52,7 +52,7 @@ __ieee754_acoshl(long double x) return __ieee754_logl(2.0*x-one/(x+__ieee754_sqrtl(t-one))); } else { /* 1<x<2 */ t = x-one; - return __log1p(t+__sqrtl(2.0*t+t*t)); + return __log1p(t+__ieee754_sqrtl(2.0*t+t*t)); } } strong_alias (__ieee754_acoshl, __acoshl_finite) diff --git a/sysdeps/ieee754/ldbl-128ibm/e_expl.c b/sysdeps/ieee754/ldbl-128ibm/e_expl.c index 82363906b0..9fd61983e3 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_expl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_expl.c @@ -70,11 +70,11 @@ static const long double C[] = { /* Smallest integer x for which e^x overflows. */ #define himark C[0] - 709.08956571282405153382846025171462914L, + 709.78271289338399678773454114191496482L, /* Largest integer x for which e^x underflows. */ #define lomark C[1] --744.44007192138121808966388925909996033L, +-744.44007192138126231410729844608163411L, /* 3x2^96 */ #define THREEp96 C[2] diff --git a/sysdeps/ieee754/ldbl-128ibm/e_logl.c b/sysdeps/ieee754/ldbl-128ibm/e_logl.c index 14f47ebade..15b5edfab3 100644 --- a/sysdeps/ieee754/ldbl-128ibm/e_logl.c +++ b/sysdeps/ieee754/ldbl-128ibm/e_logl.c @@ -182,6 +182,9 @@ static const long double ln2a = 6.93145751953125e-1L, ln2b = 1.4286068203094172321214581765680755001344E-6L; +static const long double + ldbl_epsilon = 0x1p-106L; + long double __ieee754_logl(long double x) { @@ -258,7 +261,12 @@ __ieee754_logl(long double x) } /* Series expansion of log(1+z). */ w = z * z; - y = ((((((((((((l15 * z + /* Avoid spurious underflows. */ + if (__glibc_unlikely(w <= ldbl_epsilon)) + y = 0.0L; + else + { + y = ((((((((((((l15 * z + l14) * z + l13) * z + l12) * z @@ -271,7 +279,8 @@ __ieee754_logl(long double x) + l5) * z + l4) * z + l3) * z * w; - y -= 0.5 * w; + y -= 0.5 * w; + } y += e * ln2b; /* Base 2 exponent offset times ln(2). */ y += z; y += logtbl[k-26]; /* log(t) - (t-1) */ diff --git a/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h b/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h index be9ac71cb0..1cce1fc4dc 100644 --- a/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h +++ b/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h @@ -125,7 +125,7 @@ ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64) /* Handy utility functions to pack/unpack/cononicalize and find the nearbyint of long double implemented as double double. */ static inline long double -ldbl_pack (double a, double aa) +default_ldbl_pack (double a, double aa) { union ibm_extended_long_double u; u.dd[0] = a; @@ -134,7 +134,7 @@ ldbl_pack (double a, double aa) } static inline void -ldbl_unpack (long double l, double *a, double *aa) +default_ldbl_unpack (long double l, double *a, double *aa) { union ibm_extended_long_double u; u.d = l; @@ -142,6 +142,12 @@ ldbl_unpack (long double l, double *a, double *aa) *aa = u.dd[1]; } +#ifndef ldbl_pack +# define ldbl_pack default_ldbl_pack +#endif +#ifndef ldbl_unpack +# define ldbl_unpack default_ldbl_unpack +#endif /* Convert a finite long double to canonical form. Does not handle +/-Inf properly. */ diff --git a/sysdeps/ieee754/ldbl-128ibm/w_expl.c b/sysdeps/ieee754/ldbl-128ibm/w_expl.c index a5e72b2170..70fe5f693e 100644 --- a/sysdeps/ieee754/ldbl-128ibm/w_expl.c +++ b/sysdeps/ieee754/ldbl-128ibm/w_expl.c @@ -1,6 +1,24 @@ -/* Looks like we can use ieee854 w_expl.c as is for IBM extended format. */ +#include <math.h> +#include <math_private.h> #include <math_ldbl_opt.h> -#undef weak_alias -#define weak_alias(n,a) -#include <sysdeps/ieee754/ldbl-128/w_expl.c> + +static const long double o_thres = 709.78271289338399678773454114191496482L; +static const long double u_thres = -744.44007192138126231410729844608163411L; + +long double __expl(long double x) /* wrapper exp */ +{ + long double z; + z = __ieee754_expl(x); + if (_LIB_VERSION == _IEEE_) + return z; + if (__finitel(x)) + { + if (x >= o_thres) + return __kernel_standard_l(x,x,206); /* exp overflow */ + else if (x <= u_thres) + return __kernel_standard_l(x,x,207); /* exp underflow */ + } + return z; +} +hidden_def (__expl) long_double_symbol (libm, __expl, expl); |