diff options
Diffstat (limited to 'sysdeps/ieee754/ldbl-128/lgamma_productl.c')
-rw-r--r-- | sysdeps/ieee754/ldbl-128/lgamma_productl.c | 62 |
1 files changed, 16 insertions, 46 deletions
diff --git a/sysdeps/ieee754/ldbl-128/lgamma_productl.c b/sysdeps/ieee754/ldbl-128/lgamma_productl.c index de67cbe665..fa69603aee 100644 --- a/sysdeps/ieee754/ldbl-128/lgamma_productl.c +++ b/sysdeps/ieee754/ldbl-128/lgamma_productl.c @@ -1,5 +1,5 @@ /* Compute a product of 1 + (T/X), 1 + (T/(X+1)), .... - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -18,37 +18,7 @@ #include <math.h> #include <math_private.h> -#include <float.h> - -/* Calculate X * Y exactly and store the result in *HI + *LO. It is - given that the values are small enough that no overflow occurs and - large enough (or zero) that no underflow occurs. */ - -static void -mul_split (long double *hi, long double *lo, long double x, long double y) -{ -#ifdef __FP_FAST_FMAL - /* Fast built-in fused multiply-add. */ - *hi = x * y; - *lo = __builtin_fmal (x, y, -*hi); -#elif defined FP_FAST_FMAL - /* Fast library fused multiply-add, compiler before GCC 4.6. */ - *hi = x * y; - *lo = __fmal (x, y, -*hi); -#else - /* Apply Dekker's algorithm. */ - *hi = x * y; -# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1) - long double x1 = x * C; - long double y1 = y * C; -# undef C - x1 = (x - x1) + x1; - y1 = (y - y1) + y1; - long double x2 = x - x1; - long double y2 = y - y1; - *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2; -#endif -} +#include <mul_splitl.h> /* Compute the product of 1 + (T / (X + X_EPS)), 1 + (T / (X + X_EPS + 1)), ..., 1 + (T / (X + X_EPS + N - 1)), minus 1. X is such that @@ -56,24 +26,24 @@ mul_split (long double *hi, long double *lo, long double x, long double y) X_EPS / X is small enough that factors quadratic in it can be neglected. */ -long double -__lgamma_productl (long double t, long double x, long double x_eps, int n) +_Float128 +__lgamma_productl (_Float128 t, _Float128 x, _Float128 x_eps, int n) { - long double ret = 0, ret_eps = 0; + _Float128 ret = 0, ret_eps = 0; for (int i = 0; i < n; i++) { - long double xi = x + i; - long double quot = t / xi; - long double mhi, mlo; - mul_split (&mhi, &mlo, quot, xi); - long double quot_lo = (t - mhi - mlo) / xi - t * x_eps / (xi * xi); + _Float128 xi = x + i; + _Float128 quot = t / xi; + _Float128 mhi, mlo; + mul_splitl (&mhi, &mlo, quot, xi); + _Float128 quot_lo = (t - mhi - mlo) / xi - t * x_eps / (xi * xi); /* We want (1 + RET + RET_EPS) * (1 + QUOT + QUOT_LO) - 1. */ - long double rhi, rlo; - mul_split (&rhi, &rlo, ret, quot); - long double rpq = ret + quot; - long double rpq_eps = (ret - rpq) + quot; - long double nret = rpq + rhi; - long double nret_eps = (rpq - nret) + rhi; + _Float128 rhi, rlo; + mul_splitl (&rhi, &rlo, ret, quot); + _Float128 rpq = ret + quot; + _Float128 rpq_eps = (ret - rpq) + quot; + _Float128 nret = rpq + rhi; + _Float128 nret_eps = (rpq - nret) + rhi; ret_eps += (rpq_eps + nret_eps + rlo + ret_eps * quot + quot_lo + quot_lo * (ret + ret_eps)); ret = nret; |