/* gamma.c
*
* Gamma function
*
*
*
* SYNOPSIS :
*
* double x , y , gamma ( ) ;
* extern int sgngam ;
*
* y = gamma ( x ) ;
*
*
*
* DESCRIPTION :
*
* Returns gamma function of the argument . The result is
* correctly signed , and the sign ( + 1 or - 1 ) is also
* returned in a global ( extern ) variable named sgngam .
* This variable is also filled in by the logarithmic gamma
* function lgam ( ) .
*
* Arguments | x | < = 34 are reduced by recurrence and the function
* approximated by a rational function of degree 6 / 7 in the
* interval ( 2 , 3 ) . Large arguments are handled by Stirling ' s
* formula . Large negative arguments are made positive using
* a reflection formula .
*
*
* ACCURACY :
*
* Relative error :
* arithmetic domain # trials peak rms
* DEC - 34 , 34 10000 1 . 3 e - 16 2 . 5 e - 17
* IEEE - 170 , - 33 20000 2 . 3 e - 15 3 . 3 e - 16
* IEEE - 33 , 33 20000 9 . 4 e - 16 2 . 2 e - 16
* IEEE 33 , 171 . 6 20000 2 . 3 e - 15 3 . 2 e - 16
*
* Error for arguments outside the test range will be larger
* owing to error amplification by the exponential function .
*
*/
/* lgam()
*
* Natural logarithm of gamma function
*
*
*
* SYNOPSIS :
*
* double x , y , lgam ( ) ;
* extern int sgngam ;
*
* y = lgam ( x ) ;
*
*
*
* DESCRIPTION :
*
* Returns the base e ( 2 . 718 . . . ) logarithm of the absolute
* value of the gamma function of the argument .
* The sign ( + 1 or - 1 ) of the gamma function is returned in a
* global ( extern ) variable named sgngam .
*
* For arguments greater than 13 , the logarithm of the gamma
* function is approximated by the logarithmic version of
* Stirling ' s formula using a polynomial approximation of
* degree 4 . Arguments between - 33 and + 33 are reduced by
* recurrence to the interval [ 2 , 3 ] of a rational approximation .
* The cosecant reflection formula is employed for arguments
* less than - 33 .
*
* Arguments greater than MAXLGM return MAXNUM and an error
* message . MAXLGM = 2 . 035093 e36 for DEC
* arithmetic or 2 . 556348 e305 for IEEE arithmetic .
*
*
*
* ACCURACY :
*
*
* arithmetic domain # trials peak rms
* DEC 0 , 3 7000 5 . 2 e - 17 1 . 3 e - 17
* DEC 2 . 718 , 2 . 035 e36 5000 3 . 9 e - 17 9 . 9 e - 18
* IEEE 0 , 3 28000 5 . 4 e - 16 1 . 1 e - 16
* IEEE 2 . 718 , 2 . 556 e305 40000 3 . 5 e - 16 8 . 3 e - 17
* The error criterion was relative when the function magnitude
* was greater than one but absolute when it was less than one .
*
* The following test used the relative error criterion , though
* at certain points the relative error could be much higher than
* indicated .
* IEEE - 200 , - 4 10000 4 . 8 e - 16 1 . 3 e - 16
*
*/
/* gamma.c */
/* gamma function */
/*
Cephes Math Library Release 2 . 2 : July , 1992
Copyright 1984 , 1987 , 1989 , 1992 by Stephen L . Moshier
Direct inquiries to 30 Frost Street , Cambridge , MA 02140
*/
#include "mconf.h"
#ifdef UNK
static double P[] = {
1 .60119522476751861407 E-4 ,
1 .19135147006586384913 E-3 ,
1 .04213797561761569935 E-2 ,
4 .76367800457137231464 E-2 ,
2 .07448227648435975150 E-1 ,
4 .94214826801497100753 E-1 ,
9 .99999999999999996796 E-1
};
static double Q[] = {
-2 .31581873324120129819 E-5 ,
5 .39605580493303397842 E-4 ,
-4 .45641913851797240494 E-3 ,
1 .18139785222060435552 E-2 ,
3 .58236398605498653373 E-2 ,
-2 .34591795718243348568 E-1 ,
7 .14304917030273074085 E-2 ,
1 .00000000000000000320 E0
};
#define MAXGAM 171 .624376956302725
static double LOGPI = 1 .14472988584940017414 ;
#endif
#ifdef DEC
static unsigned short P[] = {
0035047 ,0162701 ,0146301 ,0005234 ,
0035634 ,0023437 ,0032065 ,0176530 ,
0036452 ,0137157 ,0047330 ,0122574 ,
0037103 ,0017310 ,0143041 ,0017232 ,
0037524 ,0066516 ,0162563 ,0164605 ,
0037775 ,0004671 ,0146237 ,0014222 ,
0040200 ,0000000 ,0000000 ,0000000
};
static unsigned short Q[] = {
0134302 ,0041724 ,0020006 ,0116565 ,
0035415 ,0072121 ,0044251 ,0025634 ,
0136222 ,0003447 ,0035205 ,0121114 ,
0036501 ,0107552 ,0154335 ,0104271 ,
0037022 ,0135717 ,0014776 ,0171471 ,
0137560 ,0034324 ,0165024 ,0037021 ,
0037222 ,0045046 ,0047151 ,0161213 ,
0040200 ,0000000 ,0000000 ,0000000
};
#define MAXGAM 34 .84425627277176174
static unsigned short LPI[4 ] = {
0040222 ,0103202 ,0043475 ,0006750 ,
};
#define LOGPI *(double *)LPI
#endif
#ifdef IBMPC
static unsigned short P[] = {
0 x2153,0 x3998,0 xfcb8,0 x3f24,
0 xbfab,0 xe686,0 x84e3,0 x3f53,
0 x14b0,0 xe9db,0 x57cd,0 x3f85,
0 x23d3,0 x18c4,0 x63d9,0 x3fa8,
0 x7d31,0 xdcae,0 x8da9,0 x3fca,
0 xe312,0 x3993,0 xa137,0 x3fdf,
0 x0000,0 x0000,0 x0000,0 x3ff0
};
static unsigned short Q[] = {
0 xd3af,0 x8400,0 x487a,0 xbef8,
0 x2573,0 x2915,0 xae8a,0 x3f41,
0 xb44a,0 xe750,0 x40e4,0 xbf72,
0 xb117,0 x5b1b,0 x31ed,0 x3f88,
0 xde67,0 xe33f,0 x5779,0 x3fa2,
0 x87c2,0 x9d42,0 x071a,0 xbfce,
0 x3c51,0 xc9cd,0 x4944,0 x3fb2,
0 x0000,0 x0000,0 x0000,0 x3ff0
};
#define MAXGAM 171 .624376956302725
static unsigned short LPI[4 ] = {
0 xa1bd,0 x48e7,0 x50d0,0 x3ff2,
};
#define LOGPI *(double *)LPI
#endif
#ifdef MIEEE
static unsigned short P[] = {
0 x3f24,0 xfcb8,0 x3998,0 x2153,
0 x3f53,0 x84e3,0 xe686,0 xbfab,
0 x3f85,0 x57cd,0 xe9db,0 x14b0,
0 x3fa8,0 x63d9,0 x18c4,0 x23d3,
0 x3fca,0 x8da9,0 xdcae,0 x7d31,
0 x3fdf,0 xa137,0 x3993,0 xe312,
0 x3ff0,0 x0000,0 x0000,0 x0000
};
static unsigned short Q[] = {
0 xbef8,0 x487a,0 x8400,0 xd3af,
0 x3f41,0 xae8a,0 x2915,0 x2573,
0 xbf72,0 x40e4,0 xe750,0 xb44a,
0 x3f88,0 x31ed,0 x5b1b,0 xb117,
0 x3fa2,0 x5779,0 xe33f,0 xde67,
0 xbfce,0 x071a,0 x9d42,0 x87c2,
0 x3fb2,0 x4944,0 xc9cd,0 x3c51,
0 x3ff0,0 x0000,0 x0000,0 x0000
};
#define MAXGAM 171 .624376956302725
static unsigned short LPI[4 ] = {
0 x3ff2,0 x50d0,0 x48e7,0 xa1bd,
};
#define LOGPI *(double *)LPI
#endif
/* Stirling's formula for the gamma function */
#if UNK
static double STIR[5 ] = {
7 .87311395793093628397 E-4 ,
-2 .29549961613378126380 E-4 ,
-2 .68132617805781232825 E-3 ,
3 .47222221605458667310 E-3 ,
8 .33333333333482257126 E-2 ,
};
#define MAXSTIR 143 .01608
static double SQTPI = 2 .50662827463100050242 E0;
#endif
#if DEC
static unsigned short STIR[20 ] = {
0035516 ,0061622 ,0144553 ,0112224 ,
0135160 ,0131531 ,0037460 ,0165740 ,
0136057 ,0134460 ,0037242 ,0077270 ,
0036143 ,0107070 ,0156306 ,0027751 ,
0037252 ,0125252 ,0125252 ,0146064 ,
};
#define MAXSTIR 26 .77
static unsigned short SQT[4 ] = {
0040440 ,0066230 ,0177661 ,0034055 ,
};
#define SQTPI *(double *)SQT
#endif
#if IBMPC
static unsigned short STIR[20 ] = {
0 x7293,0 x592d,0 xcc72,0 x3f49,
0 x1d7c,0 x27e6,0 x166b,0 xbf2e,
0 x4fd7,0 x07d4,0 xf726,0 xbf65,
0 xc5fd,0 x1b98,0 x71c7,0 x3f6c,
0 x5986,0 x5555,0 x5555,0 x3fb5,
};
#define MAXSTIR 143 .01608
static unsigned short SQT[4 ] = {
0 x2706,0 x1ff6,0 x0d93,0 x4004,
};
#define SQTPI *(double *)SQT
#endif
#if MIEEE
static unsigned short STIR[20 ] = {
0 x3f49,0 xcc72,0 x592d,0 x7293,
0 xbf2e,0 x166b,0 x27e6,0 x1d7c,
0 xbf65,0 xf726,0 x07d4,0 x4fd7,
0 x3f6c,0 x71c7,0 x1b98,0 xc5fd,
0 x3fb5,0 x5555,0 x5555,0 x5986,
};
#define MAXSTIR 143 .01608
static unsigned short SQT[4 ] = {
0 x4004,0 x0d93,0 x1ff6,0 x2706,
};
#define SQTPI *(double *)SQT
#endif
int sgngam = 0 ;
extern int sgngam;
extern double MAXLOG, MAXNUM, PI;
#ifndef ANSIPROT
double pow(), log(), exp(), sin(), polevl(), p1evl(), floor(), fabs();
int isnan(), isfinite();
#endif
#ifdef INFINITIES
extern double INFINITY;
#endif
#ifdef NANS
extern double NAN;
#endif
/* Gamma function computed by Stirling's formula.
* The polynomial STIR is valid for 33 < = x < = 172 .
*/
static double stirf(x)
double x;
{
double y, w, v;
w = 1 .0 /x;
w = 1 .0 + w * polevl( w, STIR, 4 );
y = exp(x);
if ( x > MAXSTIR )
{ /* Avoid overflow in pow() */
v = pow( x, 0 .5 * x - 0 .25 );
y = v * (v / y);
}
else
{
y = pow( x, x - 0 .5 ) / y;
}
y = SQTPI * y * w;
return ( y );
}
double gamma(x)
double x;
{
double p, q, z;
int i;
sgngam = 1 ;
#ifdef NANS
if ( isnan(x) )
return (x);
#endif
#ifdef INFINITIES
#ifdef NANS
if ( x == INFINITY )
return (x);
if ( x == -INFINITY )
return (NAN);
#else
if ( !isfinite(x) )
return (x);
#endif
#endif
q = fabs(x);
if ( q > 33 .0 )
{
if ( x < 0 .0 )
{
p = floor(q);
if ( p == q )
{
#ifdef NANS
gamnan:
mtherr( "gamma" , DOMAIN );
return (NAN);
#else
goto goverf;
#endif
}
i = p;
if ( (i & 1 ) == 0 )
sgngam = -1 ;
z = q - p;
if ( z > 0 .5 )
{
p += 1 .0 ;
z = q - p;
}
z = q * sin( PI * z );
if ( z == 0 .0 )
{
#ifdef INFINITIES
return ( sgngam * INFINITY);
#else
goverf:
mtherr( "gamma" , OVERFLOW );
return ( sgngam * MAXNUM);
#endif
}
z = fabs(z);
z = PI/(z * stirf(q) );
}
else
{
z = stirf(x);
}
return ( sgngam * z );
}
z = 1 .0 ;
while ( x >= 3 .0 )
{
x -= 1 .0 ;
z *= x;
}
while ( x < 0 .0 )
{
if ( x > -1 .E-9 )
goto small;
z /= x;
x += 1 .0 ;
}
while ( x < 2 .0 )
{
if ( x < 1 .e-9 )
goto small;
z /= x;
x += 1 .0 ;
}
if ( x == 2 .0 )
return (z);
x -= 2 .0 ;
p = polevl( x, P, 6 );
q = polevl( x, Q, 7 );
return ( z * p / q );
small:
if ( x == 0 .0 )
{
#ifdef INFINITIES
#ifdef NANS
goto gamnan;
#else
return ( INFINITY );
#endif
#else
mtherr( "gamma" , SING );
return ( MAXNUM );
#endif
}
else
return ( z/((1 .0 + 0 .5772156649015329 * x) * x) );
}
/* A[]: Stirling's formula expansion of log gamma
* B [ ] , C [ ] : log gamma function between 2 and 3
*/
#ifdef UNK
static double A[] = {
8 .11614167470508450300 E-4 ,
-5 .95061904284301438324 E-4 ,
7 .93650340457716943945 E-4 ,
-2 .77777777730099687205 E-3 ,
8 .33333333333331927722 E-2
};
static double B[] = {
-1 .37825152569120859100 E3,
-3 .88016315134637840924 E4,
-3 .31612992738871184744 E5,
-1 .16237097492762307383 E6,
-1 .72173700820839662146 E6,
-8 .53555664245765465627 E5
};
static double C[] = {
/* 1.00000000000000000000E0, */
-3 .51815701436523470549 E2,
-1 .70642106651881159223 E4,
-2 .20528590553854454839 E5,
-1 .13933444367982507207 E6,
-2 .53252307177582951285 E6,
-2 .01889141433532773231 E6
};
/* log( sqrt( 2*pi ) ) */
static double LS2PI = 0 .91893853320467274178 ;
#define MAXLGM 2 .556348 e305
#endif
#ifdef DEC
static unsigned short A[] = {
0035524 ,0141201 ,0034633 ,0031405 ,
0135433 ,0176755 ,0126007 ,0045030 ,
0035520 ,0006371 ,0003342 ,0172730 ,
0136066 ,0005540 ,0132605 ,0026407 ,
0037252 ,0125252 ,0125252 ,0125132
};
static unsigned short B[] = {
0142654 ,0044014 ,0077633 ,0035410 ,
0144027 ,0110641 ,0125335 ,0144760 ,
0144641 ,0165637 ,0142204 ,0047447 ,
0145215 ,0162027 ,0146246 ,0155211 ,
0145322 ,0026110 ,0010317 ,0110130 ,
0145120 ,0061472 ,0120300 ,0025363
};
static unsigned short C[] = {
/*0040200,0000000,0000000,0000000*/
0142257 ,0164150 ,0163630 ,0112622 ,
0143605 ,0050153 ,0156116 ,0135272 ,
0144527 ,0056045 ,0145642 ,0062332 ,
0145213 ,0012063 ,0106250 ,0001025 ,
0145432 ,0111254 ,0044577 ,0115142 ,
0145366 ,0071133 ,0050217 ,0005122
};
/* log( sqrt( 2*pi ) ) */
static unsigned short LS2P[] = {040153 ,037616 ,041445 ,0172645 ,};
#define LS2PI *(double *)LS2P
#define MAXLGM 2 .035093 e36
#endif
#ifdef IBMPC
static unsigned short A[] = {
0 x6661,0 x2733,0 x9850,0 x3f4a,
0 xe943,0 xb580,0 x7fbd,0 xbf43,
0 x5ebb,0 x20dc,0 x019f,0 x3f4a,
0 xa5a1,0 x16b0,0 xc16c,0 xbf66,
0 x554b,0 x5555,0 x5555,0 x3fb5
};
static unsigned short B[] = {
0 x6761,0 x8ff3,0 x8901,0 xc095,
0 xb93e,0 x355b,0 xf234,0 xc0e2,
0 x89e5,0 xf890,0 x3d73,0 xc114,
0 xdb51,0 xf994,0 xbc82,0 xc131,
0 xf20b,0 x0219,0 x4589,0 xc13a,
0 x055e,0 x5418,0 x0c67,0 xc12a
};
static unsigned short C[] = {
/*0x0000,0x0000,0x0000,0x3ff0,*/
0 x12b2,0 x1cf3,0 xfd0d,0 xc075,
0 xd757,0 x7b89,0 xaa0d,0 xc0d0,
0 x4c9b,0 xb974,0 xeb84,0 xc10a,
0 x0043,0 x7195,0 x6286,0 xc131,
0 xf34c,0 x892f,0 x5255,0 xc143,
0 xe14a,0 x6a11,0 xce4b,0 xc13e
};
/* log( sqrt( 2*pi ) ) */
static unsigned short LS2P[] = {
0 xbeb5,0 xc864,0 x67f1,0 x3fed
};
#define LS2PI *(double *)LS2P
#define MAXLGM 2 .556348 e305
#endif
#ifdef MIEEE
static unsigned short A[] = {
0 x3f4a,0 x9850,0 x2733,0 x6661,
0 xbf43,0 x7fbd,0 xb580,0 xe943,
0 x3f4a,0 x019f,0 x20dc,0 x5ebb,
0 xbf66,0 xc16c,0 x16b0,0 xa5a1,
0 x3fb5,0 x5555,0 x5555,0 x554b
};
static unsigned short B[] = {
0 xc095,0 x8901,0 x8ff3,0 x6761,
0 xc0e2,0 xf234,0 x355b,0 xb93e,
0 xc114,0 x3d73,0 xf890,0 x89e5,
0 xc131,0 xbc82,0 xf994,0 xdb51,
0 xc13a,0 x4589,0 x0219,0 xf20b,
0 xc12a,0 x0c67,0 x5418,0 x055e
};
static unsigned short C[] = {
0 xc075,0 xfd0d,0 x1cf3,0 x12b2,
0 xc0d0,0 xaa0d,0 x7b89,0 xd757,
0 xc10a,0 xeb84,0 xb974,0 x4c9b,
0 xc131,0 x6286,0 x7195,0 x0043,
0 xc143,0 x5255,0 x892f,0 xf34c,
0 xc13e,0 xce4b,0 x6a11,0 xe14a
};
/* log( sqrt( 2*pi ) ) */
static unsigned short LS2P[] = {
0 x3fed,0 x67f1,0 xc864,0 xbeb5
};
#define LS2PI *(double *)LS2P
#define MAXLGM 2 .556348 e305
#endif
/* Logarithm of gamma function */
double lgam(x)
double x;
{
double p, q, u, w, z;
int i;
sgngam = 1 ;
#ifdef NANS
if ( isnan(x) )
return (x);
#endif
#ifdef INFINITIES
if ( !isfinite(x) )
return (INFINITY);
#endif
if ( x < -34 .0 )
{
q = -x;
w = lgam(q); /* note this modifies sgngam! */
p = floor(q);
if ( p == q )
{
lgsing:
#ifdef INFINITIES
mtherr( "lgam" , SING );
return (INFINITY);
#else
goto loverf;
#endif
}
i = p;
if ( (i & 1 ) == 0 )
sgngam = -1 ;
else
sgngam = 1 ;
z = q - p;
if ( z > 0 .5 )
{
p += 1 .0 ;
z = p - q;
}
z = q * sin( PI * z );
if ( z == 0 .0 )
goto lgsing;
/* z = log(PI) - log( z ) - w;*/
z = LOGPI - log( z ) - w;
return ( z );
}
if ( x < 13 .0 )
{
z = 1 .0 ;
p = 0 .0 ;
u = x;
while ( u >= 3 .0 )
{
p -= 1 .0 ;
u = x + p;
z *= u;
}
while ( u < 2 .0 )
{
if ( u == 0 .0 )
goto lgsing;
z /= u;
p += 1 .0 ;
u = x + p;
}
if ( z < 0 .0 )
{
sgngam = -1 ;
z = -z;
}
else
sgngam = 1 ;
if ( u == 2 .0 )
return ( log(z) );
p -= 2 .0 ;
x = x + p;
p = x * polevl( x, B, 5 ) / p1evl( x, C, 6 );
return ( log(z) + p );
}
if ( x > MAXLGM )
{
#ifdef INFINITIES
return ( sgngam * INFINITY );
#else
loverf:
mtherr( "lgam" , OVERFLOW );
return ( sgngam * MAXNUM );
#endif
}
q = ( x - 0 .5 ) * log(x) - x + LS2PI;
if ( x > 1 .0 e8 )
return ( q );
p = 1 .0 /(x*x);
if ( x >= 1000 .0 )
q += (( 7 .9365079365079365079365 e-4 * p
- 2 .7777777777777777777778 e-3 ) *p
+ 0 .0833333333333333333333 ) / x;
else
q += polevl( p, A, 4 ) / x;
return ( q );
}
Messung V0.5 in Prozent C=98 H=89 G=93
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-20)
¤
*© Formatika GbR, Deutschland