OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc1/] [newlib/] [libm/] [mathfp/] [er_lgamma.c] - Diff between revs 207 and 345

Only display areas with differences | Details | Blame | View Log

Rev 207 Rev 345
 
 
/* @(#)er_lgamma.c 5.1 93/09/24 */
/* @(#)er_lgamma.c 5.1 93/09/24 */
/*
/*
 * ====================================================
 * ====================================================
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 *
 *
 * Developed at SunPro, a Sun Microsystems, Inc. business.
 * Developed at SunPro, a Sun Microsystems, Inc. business.
 * Permission to use, copy, modify, and distribute this
 * Permission to use, copy, modify, and distribute this
 * software is freely granted, provided that this notice
 * software is freely granted, provided that this notice
 * is preserved.
 * is preserved.
 * ====================================================
 * ====================================================
 *
 *
 */
 */
 
 
/*
/*
FUNCTION
FUNCTION
        <<gamma>>, <<gammaf>>, <<lgamma>>, <<lgammaf>>, <<gamma_r>>,
        <<gamma>>, <<gammaf>>, <<lgamma>>, <<lgammaf>>, <<gamma_r>>,
        <<gammaf_r>>, <<lgamma_r>>, <<lgammaf_r>>---logarithmic gamma
        <<gammaf_r>>, <<lgamma_r>>, <<lgammaf_r>>---logarithmic gamma
        function
        function
INDEX
INDEX
gamma
gamma
INDEX
INDEX
gammaf
gammaf
INDEX
INDEX
lgamma
lgamma
INDEX
INDEX
lgammaf
lgammaf
INDEX
INDEX
gamma_r
gamma_r
INDEX
INDEX
gammaf_r
gammaf_r
INDEX
INDEX
lgamma_r
lgamma_r
INDEX
INDEX
lgammaf_r
lgammaf_r
 
 
ANSI_SYNOPSIS
ANSI_SYNOPSIS
#include <math.h>
#include <math.h>
double gamma(double <[x]>);
double gamma(double <[x]>);
float gammaf(float <[x]>);
float gammaf(float <[x]>);
double lgamma(double <[x]>);
double lgamma(double <[x]>);
float lgammaf(float <[x]>);
float lgammaf(float <[x]>);
double gamma_r(double <[x]>, int *<[signgamp]>);
double gamma_r(double <[x]>, int *<[signgamp]>);
float gammaf_r(float <[x]>, int *<[signgamp]>);
float gammaf_r(float <[x]>, int *<[signgamp]>);
double lgamma_r(double <[x]>, int *<[signgamp]>);
double lgamma_r(double <[x]>, int *<[signgamp]>);
float lgammaf_r(float <[x]>, int *<[signgamp]>);
float lgammaf_r(float <[x]>, int *<[signgamp]>);
 
 
TRAD_SYNOPSIS
TRAD_SYNOPSIS
#include <math.h>
#include <math.h>
double gamma(<[x]>)
double gamma(<[x]>)
double <[x]>;
double <[x]>;
float gammaf(<[x]>)
float gammaf(<[x]>)
float <[x]>;
float <[x]>;
double lgamma(<[x]>)
double lgamma(<[x]>)
double <[x]>;
double <[x]>;
float lgammaf(<[x]>)
float lgammaf(<[x]>)
float <[x]>;
float <[x]>;
double gamma_r(<[x]>, <[signgamp]>)
double gamma_r(<[x]>, <[signgamp]>)
double <[x]>;
double <[x]>;
int <[signgamp]>;
int <[signgamp]>;
float gammaf_r(<[x]>, <[signgamp]>)
float gammaf_r(<[x]>, <[signgamp]>)
float <[x]>;
float <[x]>;
int <[signgamp]>;
int <[signgamp]>;
double lgamma_r(<[x]>, <[signgamp]>)
double lgamma_r(<[x]>, <[signgamp]>)
double <[x]>;
double <[x]>;
int <[signgamp]>;
int <[signgamp]>;
float lgammaf_r(<[x]>, <[signgamp]>)
float lgammaf_r(<[x]>, <[signgamp]>)
float <[x]>;
float <[x]>;
int <[signgamp]>;
int <[signgamp]>;
 
 
DESCRIPTION
DESCRIPTION
<<gamma>> calculates
<<gamma>> calculates
@tex
@tex
$\mit ln\bigl(\Gamma(x)\bigr)$,
$\mit ln\bigl(\Gamma(x)\bigr)$,
@end tex
@end tex
the natural logarithm of the gamma function of <[x]>.  The gamma function
the natural logarithm of the gamma function of <[x]>.  The gamma function
(<<exp(gamma(<[x]>))>>) is a generalization of factorial, and retains
(<<exp(gamma(<[x]>))>>) is a generalization of factorial, and retains
the property that
the property that
@ifnottex
@ifnottex
<<exp(gamma(N))>> is equivalent to <<N*exp(gamma(N-1))>>.
<<exp(gamma(N))>> is equivalent to <<N*exp(gamma(N-1))>>.
@end ifnottex
@end ifnottex
@tex
@tex
$\mit \Gamma(N)\equiv N\times\Gamma(N-1)$.
$\mit \Gamma(N)\equiv N\times\Gamma(N-1)$.
@end tex
@end tex
Accordingly, the results of the gamma function itself grow very
Accordingly, the results of the gamma function itself grow very
quickly.  <<gamma>> is defined as
quickly.  <<gamma>> is defined as
@tex
@tex
$\mit ln\bigl(\Gamma(x)\bigr)$ rather than simply $\mit \Gamma(x)$
$\mit ln\bigl(\Gamma(x)\bigr)$ rather than simply $\mit \Gamma(x)$
@end tex
@end tex
@ifnottex
@ifnottex
the natural log of the gamma function, rather than the gamma function
the natural log of the gamma function, rather than the gamma function
itself,
itself,
@end ifnottex
@end ifnottex
to extend the useful range of results representable.
to extend the useful range of results representable.
 
 
The sign of the result is returned in the global variable <<signgam>>,
The sign of the result is returned in the global variable <<signgam>>,
which is declared in math.h.
which is declared in math.h.
 
 
<<gammaf>> performs the same calculation as <<gamma>>, but uses and
<<gammaf>> performs the same calculation as <<gamma>>, but uses and
returns <<float>> values.
returns <<float>> values.
 
 
<<lgamma>> and <<lgammaf>> are alternate names for <<gamma>> and
<<lgamma>> and <<lgammaf>> are alternate names for <<gamma>> and
<<gammaf>>.  The use of <<lgamma>> instead of <<gamma>> is a reminder
<<gammaf>>.  The use of <<lgamma>> instead of <<gamma>> is a reminder
that these functions compute the log of the gamma function, rather
that these functions compute the log of the gamma function, rather
than the gamma function itself.
than the gamma function itself.
 
 
The functions <<gamma_r>>, <<gammaf_r>>, <<lgamma_r>>, and
The functions <<gamma_r>>, <<gammaf_r>>, <<lgamma_r>>, and
<<lgammaf_r>> are just like <<gamma>>, <<gammaf>>, <<lgamma>>, and
<<lgammaf_r>> are just like <<gamma>>, <<gammaf>>, <<lgamma>>, and
<<lgammaf>>, respectively, but take an additional argument.  This
<<lgammaf>>, respectively, but take an additional argument.  This
additional argument is a pointer to an integer.  This additional
additional argument is a pointer to an integer.  This additional
argument is used to return the sign of the result, and the global
argument is used to return the sign of the result, and the global
variable <<signgam>> is not used.  These functions may be used for
variable <<signgam>> is not used.  These functions may be used for
reentrant calls (but they will still set the global variable <<errno>>
reentrant calls (but they will still set the global variable <<errno>>
if an error occurs).
if an error occurs).
 
 
RETURNS
RETURNS
Normally, the computed result is returned.
Normally, the computed result is returned.
 
 
When <[x]> is a nonpositive integer, <<gamma>> returns <<HUGE_VAL>>
When <[x]> is a nonpositive integer, <<gamma>> returns <<HUGE_VAL>>
and <<errno>> is set to <<EDOM>>.  If the result overflows, <<gamma>>
and <<errno>> is set to <<EDOM>>.  If the result overflows, <<gamma>>
returns <<HUGE_VAL>> and <<errno>> is set to <<ERANGE>>.
returns <<HUGE_VAL>> and <<errno>> is set to <<ERANGE>>.
 
 
You can modify this error treatment using <<matherr>>.
You can modify this error treatment using <<matherr>>.
 
 
PORTABILITY
PORTABILITY
Neither <<gamma>> nor <<gammaf>> is ANSI C.  */
Neither <<gamma>> nor <<gammaf>> is ANSI C.  */
 
 
/* lgamma_r(x, signgamp)
/* lgamma_r(x, signgamp)
 * Reentrant version of the logarithm of the Gamma function
 * Reentrant version of the logarithm of the Gamma function
 * with user provide pointer for the sign of Gamma(x).
 * with user provide pointer for the sign of Gamma(x).
 *
 *
 * Method:
 * Method:
 *   1. Argument Reduction for 0 < x <= 8
 *   1. Argument Reduction for 0 < x <= 8
 *      Since gamma(1+s)=s*gamma(s), for x in [0,8], we may
 *      Since gamma(1+s)=s*gamma(s), for x in [0,8], we may
 *      reduce x to a number in [1.5,2.5] by
 *      reduce x to a number in [1.5,2.5] by
 *              lgamma(1+s) = log(s) + lgamma(s)
 *              lgamma(1+s) = log(s) + lgamma(s)
 *      for example,
 *      for example,
 *              lgamma(7.3) = log(6.3) + lgamma(6.3)
 *              lgamma(7.3) = log(6.3) + lgamma(6.3)
 *                          = log(6.3*5.3) + lgamma(5.3)
 *                          = log(6.3*5.3) + lgamma(5.3)
 *                          = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
 *                          = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
 *   2. Polynomial approximation of lgamma around its
 *   2. Polynomial approximation of lgamma around its
 *      minimun ymin=1.461632144968362245 to maintain monotonicity.
 *      minimun ymin=1.461632144968362245 to maintain monotonicity.
 *      On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
 *      On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
 *              Let z = x-ymin;
 *              Let z = x-ymin;
 *              lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
 *              lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
 *      where
 *      where
 *              poly(z) is a 14 degree polynomial.
 *              poly(z) is a 14 degree polynomial.
 *   2. Rational approximation in the primary interval [2,3]
 *   2. Rational approximation in the primary interval [2,3]
 *      We use the following approximation:
 *      We use the following approximation:
 *              s = x-2.0;
 *              s = x-2.0;
 *              lgamma(x) = 0.5*s + s*P(s)/Q(s)
 *              lgamma(x) = 0.5*s + s*P(s)/Q(s)
 *      with accuracy
 *      with accuracy
 *              |P/Q - (lgamma(x)-0.5s)| < 2**-61.71
 *              |P/Q - (lgamma(x)-0.5s)| < 2**-61.71
 *      Our algorithms are based on the following observation
 *      Our algorithms are based on the following observation
 *
 *
 *                             zeta(2)-1    2    zeta(3)-1    3
 *                             zeta(2)-1    2    zeta(3)-1    3
 * lgamma(2+s) = s*(1-Euler) + --------- * s  -  --------- * s  + ...
 * lgamma(2+s) = s*(1-Euler) + --------- * s  -  --------- * s  + ...
 *                                 2                 3
 *                                 2                 3
 *
 *
 *      where Euler = 0.5771... is the Euler constant, which is very
 *      where Euler = 0.5771... is the Euler constant, which is very
 *      close to 0.5.
 *      close to 0.5.
 *
 *
 *   3. For x>=8, we have
 *   3. For x>=8, we have
 *      lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
 *      lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
 *      (better formula:
 *      (better formula:
 *         lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
 *         lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
 *      Let z = 1/x, then we approximation
 *      Let z = 1/x, then we approximation
 *              f(z) = lgamma(x) - (x-0.5)(log(x)-1)
 *              f(z) = lgamma(x) - (x-0.5)(log(x)-1)
 *      by
 *      by
 *                                  3       5             11
 *                                  3       5             11
 *              w = w0 + w1*z + w2*z  + w3*z  + ... + w6*z
 *              w = w0 + w1*z + w2*z  + w3*z  + ... + w6*z
 *      where
 *      where
 *              |w - f(z)| < 2**-58.74
 *              |w - f(z)| < 2**-58.74
 *
 *
 *   4. For negative x, since (G is gamma function)
 *   4. For negative x, since (G is gamma function)
 *              -x*G(-x)*G(x) = pi/sin(pi*x),
 *              -x*G(-x)*G(x) = pi/sin(pi*x),
 *      we have
 *      we have
 *              G(x) = pi/(sin(pi*x)*(-x)*G(-x))
 *              G(x) = pi/(sin(pi*x)*(-x)*G(-x))
 *      since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
 *      since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
 *      Hence, for x<0, signgam = sign(sin(pi*x)) and
 *      Hence, for x<0, signgam = sign(sin(pi*x)) and
 *              lgamma(x) = log(|Gamma(x)|)
 *              lgamma(x) = log(|Gamma(x)|)
 *                        = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
 *                        = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
 *      Note: one should avoid compute pi*(-x) directly in the
 *      Note: one should avoid compute pi*(-x) directly in the
 *            computation of sin(pi*(-x)).
 *            computation of sin(pi*(-x)).
 *
 *
 *   5. Special Cases
 *   5. Special Cases
 *              lgamma(2+s) ~ s*(1-Euler) for tiny s
 *              lgamma(2+s) ~ s*(1-Euler) for tiny s
 *              lgamma(1)=lgamma(2)=0
 *              lgamma(1)=lgamma(2)=0
 *              lgamma(x) ~ -log(x) for tiny x
 *              lgamma(x) ~ -log(x) for tiny x
 *              lgamma(0) = lgamma(inf) = inf
 *              lgamma(0) = lgamma(inf) = inf
 *              lgamma(-integer) = +-inf
 *              lgamma(-integer) = +-inf
 *
 *
 */
 */
 
 
#include "fdlibm.h"
#include "fdlibm.h"
 
 
#ifdef __STDC__
#ifdef __STDC__
static const double
static const double
#else
#else
static double
static double
#endif
#endif
two52=  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
two52=  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
half=  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
half=  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
pi  =  3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
pi  =  3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
a0  =  7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */
a0  =  7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */
a1  =  3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */
a1  =  3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */
a2  =  6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */
a2  =  6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */
a3  =  2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */
a3  =  2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */
a4  =  7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */
a4  =  7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */
a5  =  2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */
a5  =  2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */
a6  =  1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */
a6  =  1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */
a7  =  5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */
a7  =  5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */
a8  =  2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */
a8  =  2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */
a9  =  1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */
a9  =  1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */
a10 =  2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */
a10 =  2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */
a11 =  4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */
a11 =  4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */
tc  =  1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */
tc  =  1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */
tf  = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */
tf  = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */
/* tt = -(tail of tf) */
/* tt = -(tail of tf) */
tt  = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */
tt  = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */
t0  =  4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */
t0  =  4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */
t1  = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */
t1  = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */
t2  =  6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */
t2  =  6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */
t3  = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */
t3  = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */
t4  =  1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */
t4  =  1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */
t5  = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */
t5  = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */
t6  =  6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */
t6  =  6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */
t7  = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */
t7  = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */
t8  =  2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */
t8  =  2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */
t9  = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */
t9  = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */
t10 =  8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */
t10 =  8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */
t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */
t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */
t12 =  3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */
t12 =  3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */
t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */
t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */
t14 =  3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */
t14 =  3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */
u0  = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
u0  = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
u1  =  6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */
u1  =  6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */
u2  =  1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */
u2  =  1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */
u3  =  9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */
u3  =  9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */
u4  =  2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */
u4  =  2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */
u5  =  1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */
u5  =  1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */
v1  =  2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */
v1  =  2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */
v2  =  2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */
v2  =  2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */
v3  =  7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */
v3  =  7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */
v4  =  1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */
v4  =  1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */
v5  =  3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */
v5  =  3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */
s0  = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
s0  = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
s1  =  2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */
s1  =  2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */
s2  =  3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */
s2  =  3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */
s3  =  1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */
s3  =  1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */
s4  =  2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */
s4  =  2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */
s5  =  1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */
s5  =  1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */
s6  =  3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */
s6  =  3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */
r1  =  1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */
r1  =  1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */
r2  =  7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */
r2  =  7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */
r3  =  1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */
r3  =  1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */
r4  =  1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */
r4  =  1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */
r5  =  7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */
r5  =  7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */
r6  =  7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */
r6  =  7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */
w0  =  4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */
w0  =  4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */
w1  =  8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */
w1  =  8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */
w2  = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */
w2  = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */
w3  =  7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */
w3  =  7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */
w4  = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */
w4  = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */
w5  =  8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */
w5  =  8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */
w6  = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */
w6  = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */
 
 
#ifdef __STDC__
#ifdef __STDC__
static const double zero=  0.00000000000000000000e+00;
static const double zero=  0.00000000000000000000e+00;
#else
#else
static double zero=  0.00000000000000000000e+00;
static double zero=  0.00000000000000000000e+00;
#endif
#endif
 
 
#ifdef __STDC__
#ifdef __STDC__
        static double sin_pi(double x)
        static double sin_pi(double x)
#else
#else
        static double sin_pi(x)
        static double sin_pi(x)
        double x;
        double x;
#endif
#endif
{
{
        double y,z;
        double y,z;
        __int32_t n,ix;
        __int32_t n,ix;
 
 
        GET_HIGH_WORD(ix,x);
        GET_HIGH_WORD(ix,x);
        ix &= 0x7fffffff;
        ix &= 0x7fffffff;
 
 
        if(ix<0x3fd00000) return sin(pi*x);
        if(ix<0x3fd00000) return sin(pi*x);
        y = -x;         /* x is assume negative */
        y = -x;         /* x is assume negative */
 
 
    /*
    /*
     * argument reduction, make sure inexact flag not raised if input
     * argument reduction, make sure inexact flag not raised if input
     * is an integer
     * is an integer
     */
     */
        z = floor(y);
        z = floor(y);
        if(z!=y) {                              /* inexact anyway */
        if(z!=y) {                              /* inexact anyway */
            y  *= 0.5;
            y  *= 0.5;
            y   = 2.0*(y - floor(y));           /* y = |x| mod 2.0 */
            y   = 2.0*(y - floor(y));           /* y = |x| mod 2.0 */
            n   = (__int32_t) (y*4.0);
            n   = (__int32_t) (y*4.0);
        } else {
        } else {
            if(ix>=0x43400000) {
            if(ix>=0x43400000) {
                y = zero; n = 0;                 /* y must be even */
                y = zero; n = 0;                 /* y must be even */
            } else {
            } else {
                if(ix<0x43300000) z = y+two52;  /* exact */
                if(ix<0x43300000) z = y+two52;  /* exact */
                GET_LOW_WORD(n,z);
                GET_LOW_WORD(n,z);
                n &= 1;
                n &= 1;
                y  = n;
                y  = n;
                n<<= 2;
                n<<= 2;
            }
            }
        }
        }
        switch (n) {
        switch (n) {
            case 0:   y =  sin(pi*y); break;
            case 0:   y =  sin(pi*y); break;
            case 1:
            case 1:
            case 2:   y =  cos(pi*(0.5-y)); break;
            case 2:   y =  cos(pi*(0.5-y)); break;
            case 3:
            case 3:
            case 4:   y =  sin(pi*(one-y)); break;
            case 4:   y =  sin(pi*(one-y)); break;
            case 5:
            case 5:
            case 6:   y = -cos(pi*(y-1.5)); break;
            case 6:   y = -cos(pi*(y-1.5)); break;
            default:  y =  sin(pi*(y-2.0)); break;
            default:  y =  sin(pi*(y-2.0)); break;
            }
            }
        return -y;
        return -y;
}
}
 
 
 
 
#ifdef __STDC__
#ifdef __STDC__
        double lgamma_r(double x, int *signgamp)
        double lgamma_r(double x, int *signgamp)
#else
#else
        double lgamma_r(x,signgamp)
        double lgamma_r(x,signgamp)
        double x; int *signgamp;
        double x; int *signgamp;
#endif
#endif
{
{
        double t,y,z,nadj,p,p1,p2,p3,q,r,w;
        double t,y,z,nadj,p,p1,p2,p3,q,r,w;
        __int32_t i,hx,lx,ix;
        __int32_t i,hx,lx,ix;
 
 
        nadj = 0;
        nadj = 0;
 
 
        EXTRACT_WORDS(hx,lx,x);
        EXTRACT_WORDS(hx,lx,x);
 
 
    /* purge off +-inf, NaN, +-0, and negative arguments */
    /* purge off +-inf, NaN, +-0, and negative arguments */
        *signgamp = 1;
        *signgamp = 1;
        ix = hx&0x7fffffff;
        ix = hx&0x7fffffff;
        if(ix>=0x7ff00000) return x*x;
        if(ix>=0x7ff00000) return x*x;
        if((ix|lx)==0) return one/zero;
        if((ix|lx)==0) return one/zero;
        if(ix<0x3b900000) {     /* |x|<2**-70, return -log(|x|) */
        if(ix<0x3b900000) {     /* |x|<2**-70, return -log(|x|) */
            if(hx<0) {
            if(hx<0) {
                *signgamp = -1;
                *signgamp = -1;
                return -log(-x);
                return -log(-x);
            } else return -log(x);
            } else return -log(x);
        }
        }
        if(hx<0) {
        if(hx<0) {
            if(ix>=0x43300000)  /* |x|>=2**52, must be -integer */
            if(ix>=0x43300000)  /* |x|>=2**52, must be -integer */
                return one/zero;
                return one/zero;
            t = sin_pi(x);
            t = sin_pi(x);
            if(t==zero) return one/zero; /* -integer */
            if(t==zero) return one/zero; /* -integer */
            nadj = log(pi/fabs(t*x));
            nadj = log(pi/fabs(t*x));
            if(t<zero) *signgamp = -1;
            if(t<zero) *signgamp = -1;
            x = -x;
            x = -x;
        }
        }
 
 
    /* purge off 1 and 2 */
    /* purge off 1 and 2 */
        if((((ix-0x3ff00000)|lx)==0)||(((ix-0x40000000)|lx)==0)) r = 0;
        if((((ix-0x3ff00000)|lx)==0)||(((ix-0x40000000)|lx)==0)) r = 0;
    /* for x < 2.0 */
    /* for x < 2.0 */
        else if(ix<0x40000000) {
        else if(ix<0x40000000) {
            if(ix<=0x3feccccc) {        /* lgamma(x) = lgamma(x+1)-log(x) */
            if(ix<=0x3feccccc) {        /* lgamma(x) = lgamma(x+1)-log(x) */
                r = -log(x);
                r = -log(x);
                if(ix>=0x3FE76944) {y = one-x; i= 0;}
                if(ix>=0x3FE76944) {y = one-x; i= 0;}
                else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;}
                else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;}
                else {y = x; i=2;}
                else {y = x; i=2;}
            } else {
            } else {
                r = zero;
                r = zero;
                if(ix>=0x3FFBB4C3) {y=2.0-x;i=0;} /* [1.7316,2] */
                if(ix>=0x3FFBB4C3) {y=2.0-x;i=0;} /* [1.7316,2] */
                else if(ix>=0x3FF3B4C4) {y=x-tc;i=1;} /* [1.23,1.73] */
                else if(ix>=0x3FF3B4C4) {y=x-tc;i=1;} /* [1.23,1.73] */
                else {y=x-one;i=2;}
                else {y=x-one;i=2;}
            }
            }
            switch(i) {
            switch(i) {
              case 0:
              case 0:
                z = y*y;
                z = y*y;
                p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
                p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
                p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
                p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
                p  = y*p1+p2;
                p  = y*p1+p2;
                r  += (p-0.5*y); break;
                r  += (p-0.5*y); break;
              case 1:
              case 1:
                z = y*y;
                z = y*y;
                w = z*y;
                w = z*y;
                p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12)));    /* parallel comp */
                p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12)));    /* parallel comp */
                p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
                p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
                p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
                p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
                p  = z*p1-(tt-w*(p2+y*p3));
                p  = z*p1-(tt-w*(p2+y*p3));
                r += (tf + p); break;
                r += (tf + p); break;
              case 2:
              case 2:
                p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
                p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
                p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
                p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
                r += (-0.5*y + p1/p2);
                r += (-0.5*y + p1/p2);
            }
            }
        }
        }
        else if(ix<0x40200000) {                        /* x < 8.0 */
        else if(ix<0x40200000) {                        /* x < 8.0 */
            i = (__int32_t)x;
            i = (__int32_t)x;
            t = zero;
            t = zero;
            y = x-(double)i;
            y = x-(double)i;
            p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
            p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
            q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
            q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
            r = half*y+p/q;
            r = half*y+p/q;
            z = one;    /* lgamma(1+s) = log(s) + lgamma(s) */
            z = one;    /* lgamma(1+s) = log(s) + lgamma(s) */
            switch(i) {
            switch(i) {
            case 7: z *= (y+6.0);       /* FALLTHRU */
            case 7: z *= (y+6.0);       /* FALLTHRU */
            case 6: z *= (y+5.0);       /* FALLTHRU */
            case 6: z *= (y+5.0);       /* FALLTHRU */
            case 5: z *= (y+4.0);       /* FALLTHRU */
            case 5: z *= (y+4.0);       /* FALLTHRU */
            case 4: z *= (y+3.0);       /* FALLTHRU */
            case 4: z *= (y+3.0);       /* FALLTHRU */
            case 3: z *= (y+2.0);       /* FALLTHRU */
            case 3: z *= (y+2.0);       /* FALLTHRU */
                    r += log(z); break;
                    r += log(z); break;
            }
            }
    /* 8.0 <= x < 2**58 */
    /* 8.0 <= x < 2**58 */
        } else if (ix < 0x43900000) {
        } else if (ix < 0x43900000) {
            t = log(x);
            t = log(x);
            z = one/x;
            z = one/x;
            y = z*z;
            y = z*z;
            w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
            w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
            r = (x-half)*(t-one)+w;
            r = (x-half)*(t-one)+w;
        } else
        } else
    /* 2**58 <= x <= inf */
    /* 2**58 <= x <= inf */
            r =  x*(log(x)-one);
            r =  x*(log(x)-one);
        if(hx<0) r = nadj - r;
        if(hx<0) r = nadj - r;
        return r;
        return r;
}
}
 
 
double
double
lgamma(double x)
lgamma(double x)
{
{
  return lgamma_r(x, &(_REENT_SIGNGAM(_REENT)));
  return lgamma_r(x, &(_REENT_SIGNGAM(_REENT)));
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.