/**
 * This file has no copyright assigned and is placed in the Public Domain.
 * This file is part of the w64 mingw-runtime package.
 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
 */
#include "cephes_mconf.h"

/* define MAXGAM 34.84425627277176174 */

/* Stirling's formula for the gamma function
 * gamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) ( 1 + 1/x P(1/x) )
 * .028 < 1/x < .1
 * relative error < 1.9e-11
 */
static const float STIR[] = {
  -2.705194986674176E-003,
   3.473255786154910E-003,
   8.333331788340907E-002,
};
static const float MAXSTIR = 26.77;
static const float SQTPIF = 2.50662827463100050242; /* sqrt( 2 pi ) */

static float stirf(float);

/* Gamma function computed by Stirling's formula,
 * sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x))
 * The polynomial STIR is valid for 33 <= x <= 172.
 */
static float stirf( float x )
{
	float  y, w, v;

	w = 1.0/x;
	w = 1.0 + w * polevlf(w, STIR, 2);
	y = expf(-x);
	if (x > MAXSTIR)
	{ /* Avoid overflow in pow() */
		v = powf(x, 0.5 * x - 0.25);
		y *= v;
		y *= v;
	}
	else
	{
		y = powf(x, x - 0.5) * y;
	}
	y = SQTPIF * y * w;
	return (y);
}


/* gamma(x+2), 0 < x < 1 */
static const float P[] = {
  1.536830450601906E-003,
  5.397581592950993E-003,
  4.130370201859976E-003,
  7.232307985516519E-002,
  8.203960091619193E-002,
  4.117857447645796E-001,
  4.227867745131584E-001,
  9.999999822945073E-001,
};

float __tgammaf_r( float x, int* sgngamf);

float __tgammaf_r( float x, int* sgngamf)
{
	float p, q, z, nz;
	int i, direction, negative;

#ifdef NANS
	if (isnan(x))
		return (x);
#endif
#ifdef INFINITIES
#ifdef NANS
	if (x == INFINITYF)
		return (x);
	if (x == -INFINITYF)
		return (NANF);
#else
	if (!isfinite(x))
		return (x);
#endif
#endif

	*sgngamf = 1;
	negative = 0;
	nz = 0.0;
	if (x < 0.0)
	{
		negative = 1;
		q = -x;
		p = floorf(q);
		if (p == q)
		{
gsing:
			_SET_ERRNO(EDOM);
			mtherr("tgammaf", SING);
#ifdef INFINITIES
			return (INFINITYF);
#else
			return (MAXNUMF);
#endif
		}
		i = p;
		if ((i & 1) == 0)
			*sgngamf = -1;
		nz = q - p;
		if (nz > 0.5)
		{
			p += 1.0;
			nz = q - p;
		}
		nz = q * sinf(PIF * nz);
		if (nz == 0.0)
		{
			_SET_ERRNO(ERANGE);
			mtherr("tgamma", OVERFLOW);
#ifdef INFINITIES
			return(*sgngamf * INFINITYF);
#else
			return(*sgngamf * MAXNUMF);
#endif
		}
		if (nz < 0)
			nz = -nz;
		x = q;
	}
	if (x >= 10.0)
	{
		z = stirf(x);
	}
	if (x < 2.0)
		direction = 1;
	else
		direction = 0;
	z = 1.0;
	while (x >= 3.0)
	{
		x -= 1.0;
		z *= x;
	}
	/*
	while (x < 0.0)
	{
		if (x > -1.E-4)
			goto Small;
		z *=x;
		x += 1.0;
	}
	*/
	while (x < 2.0)
	{
		if (x < 1.e-4)
			goto Small;
		z *=x;
		x += 1.0;
	}

	if (direction)
		z = 1.0/z;

	if (x == 2.0)
		return (z);

	x -= 2.0;
	p = z * polevlf(x, P, 7);

gdone:
	if (negative)
	{
		p = *sgngamf * PIF/(nz * p );
	}
	return (p);

Small:
	if (x == 0.0)
	{
		goto gsing;
	}
	else
	{
		p = z / ((1.0 + 0.5772156649015329 * x) * x);
		goto gdone;
	}
}

/* This is the C99 version */
float tgammaf(float x)
{
	int local_sgngamf = 0;
	return (__tgammaf_r(x, &local_sgngamf));
}

