/* Implementation of gamma function according to ISO C.
   Copyright (C) 1997-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
		  Jakub Jelinek <jj@ultra.linux.cz, 1999.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <math.h>
#include <math_private.h>
#include <float.h>

/* Coefficients B_2k / 2k(2k-1) of x^-(2k-1) inside exp in Stirling's
   approximation to gamma function.  */

static const long double gamma_coeff[] =
  {
    0x1.5555555555555555555555555555p-4L,
    -0xb.60b60b60b60b60b60b60b60b60b8p-12L,
    0x3.4034034034034034034034034034p-12L,
    -0x2.7027027027027027027027027028p-12L,
    0x3.72a3c5631fe46ae1d4e700dca8f2p-12L,
    -0x7.daac36664f1f207daac36664f1f4p-12L,
    0x1.a41a41a41a41a41a41a41a41a41ap-8L,
    -0x7.90a1b2c3d4e5f708192a3b4c5d7p-8L,
    0x2.dfd2c703c0cfff430edfd2c703cp-4L,
    -0x1.6476701181f39edbdb9ce625987dp+0L,
    0xd.672219167002d3a7a9c886459cp+0L,
    -0x9.cd9292e6660d55b3f712eb9e07c8p+4L,
    0x8.911a740da740da740da740da741p+8L,
    -0x8.d0cc570e255bf59ff6eec24b49p+12L,
  };

#define NCOEFF (sizeof (gamma_coeff) / sizeof (gamma_coeff[0]))

/* Return gamma (X), for positive X less than 1775, in the form R *
   2^(*EXP2_ADJ), where R is the return value and *EXP2_ADJ is set to
   avoid overflow or underflow in intermediate calculations.  */

static long double
gammal_positive (long double x, int *exp2_adj)
{
  int local_signgam;
  if (x < 0.5L)
    {
      *exp2_adj = 0;
      return __ieee754_expl (__ieee754_lgammal_r (x + 1, &local_signgam)) / x;
    }
  else if (x <= 1.5L)
    {
      *exp2_adj = 0;
      return __ieee754_expl (__ieee754_lgammal_r (x, &local_signgam));
    }
  else if (x < 12.5L)
    {
      /* Adjust into the range for using exp (lgamma).  */
      *exp2_adj = 0;
      long double n = __ceill (x - 1.5L);
      long double x_adj = x - n;
      long double eps;
      long double prod = __gamma_productl (x_adj, 0, n, &eps);
      return (__ieee754_expl (__ieee754_lgammal_r (x_adj, &local_signgam))
	      * prod * (1.0L + eps));
    }
  else
    {
      long double eps = 0;
      long double x_eps = 0;
      long double x_adj = x;
      long double prod = 1;
      if (x < 24.0L)
	{
	  /* Adjust into the range for applying Stirling's
	     approximation.  */
	  long double n = __ceill (24.0L - x);
	  x_adj = x + n;
	  x_eps = (x - (x_adj - n));
	  prod = __gamma_productl (x_adj - n, x_eps, n, &eps);
	}
      /* The result is now gamma (X_ADJ + X_EPS) / (PROD * (1 + EPS)).
	 Compute gamma (X_ADJ + X_EPS) using Stirling's approximation,
	 starting by computing pow (X_ADJ, X_ADJ) with a power of 2
	 factored out.  */
      long double exp_adj = -eps;
      long double x_adj_int = __roundl (x_adj);
      long double x_adj_frac = x_adj - x_adj_int;
      int x_adj_log2;
      long double x_adj_mant = __frexpl (x_adj, &x_adj_log2);
      if (x_adj_mant < M_SQRT1_2l)
	{
	  x_adj_log2--;
	  x_adj_mant *= 2.0L;
	}
      *exp2_adj = x_adj_log2 * (int) x_adj_int;
      long double ret = (__ieee754_powl (x_adj_mant, x_adj)
			 * __ieee754_exp2l (x_adj_log2 * x_adj_frac)
			 * __ieee754_expl (-x_adj)
			 * __ieee754_sqrtl (2 * M_PIl / x_adj)
			 / prod);
      exp_adj += x_eps * __ieee754_logl (x);
      long double bsum = gamma_coeff[NCOEFF - 1];
      long double x_adj2 = x_adj * x_adj;
      for (size_t i = 1; i <= NCOEFF - 1; i++)
	bsum = bsum / x_adj2 + gamma_coeff[NCOEFF - 1 - i];
      exp_adj += bsum / x_adj;
      return ret + ret * __expm1l (exp_adj);
    }
}

long double
__ieee754_gammal_r (long double x, int *signgamp)
{
  int64_t hx;
  u_int64_t lx;

  GET_LDOUBLE_WORDS64 (hx, lx, x);

  if (((hx & 0x7fffffffffffffffLL) | lx) == 0)
    {
      /* Return value for x == 0 is Inf with divide by zero exception.  */
      *signgamp = 0;
      return 1.0 / x;
    }
  if (hx < 0 && (u_int64_t) hx < 0xffff000000000000ULL && __rintl (x) == x)
    {
      /* Return value for integer x < 0 is NaN with invalid exception.  */
      *signgamp = 0;
      return (x - x) / (x - x);
    }
  if (hx == 0xffff000000000000ULL && lx == 0)
    {
      /* x == -Inf.  According to ISO this is NaN.  */
      *signgamp = 0;
      return x - x;
    }
  if ((hx & 0x7fff000000000000ULL) == 0x7fff000000000000ULL)
    {
      /* Positive infinity (return positive infinity) or NaN (return
	 NaN).  */
      *signgamp = 0;
      return x + x;
    }

  if (x >= 1756.0L)
    {
      /* Overflow.  */
      *signgamp = 0;
      return LDBL_MAX * LDBL_MAX;
    }
  else if (x > 0.0L)
    {
      *signgamp = 0;
      int exp2_adj;
      long double ret = gammal_positive (x, &exp2_adj);
      return __scalbnl (ret, exp2_adj);
    }
  else if (x >= -LDBL_EPSILON / 4.0L)
    {
      *signgamp = 0;
      return 1.0f / x;
    }
  else
    {
      long double tx = __truncl (x);
      *signgamp = (tx == 2.0L * __truncl (tx / 2.0L)) ? -1 : 1;
      if (x <= -1775.0L)
	/* Underflow.  */
	return LDBL_MIN * LDBL_MIN;
      long double frac = tx - x;
      if (frac > 0.5L)
	frac = 1.0L - frac;
      long double sinpix = (frac <= 0.25L
			    ? __sinl (M_PIl * frac)
			    : __cosl (M_PIl * (0.5L - frac)));
      int exp2_adj;
      long double ret = M_PIl / (-x * sinpix
				 * gammal_positive (-x, &exp2_adj));
      return __scalbnl (ret, -exp2_adj);
    }
}
strong_alias (__ieee754_gammal_r, __gammal_r_finite)
