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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [newlib-1.18.0/] [newlib/] [libm/] [math/] [w_gamma.c] - Diff between revs 207 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 207 Rev 816
 
 
/* @(#)w_gamma.c 5.1 93/09/24 */
/* @(#)w_gamma.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.
 * ====================================================
 * ====================================================
 *
 *
 */
 */
 
 
/* BUG:  FIXME?
/* BUG:  FIXME?
     According to Linux man pages for tgamma, lgamma, and gamma, the gamma
     According to Linux man pages for tgamma, lgamma, and gamma, the gamma
function was originally defined in BSD as implemented here--the log of the gamma
function was originally defined in BSD as implemented here--the log of the gamma
function.  BSD 4.3 changed the name to lgamma, apparently removing gamma.  BSD
function.  BSD 4.3 changed the name to lgamma, apparently removing gamma.  BSD
4.4 re-introduced the gamma name with the more intuitive, without logarithm,
4.4 re-introduced the gamma name with the more intuitive, without logarithm,
plain gamma function.  The C99 standard apparently wanted to avoid a problem
plain gamma function.  The C99 standard apparently wanted to avoid a problem
with the poorly-named earlier gamma and used tgamma when adding a plain
with the poorly-named earlier gamma and used tgamma when adding a plain
gamma function.
gamma function.
     So the current gamma is matching an old, bad definition, and not
     So the current gamma is matching an old, bad definition, and not
matching a newer, better definition.  */
matching a newer, better definition.  */
/*
/*
FUNCTION
FUNCTION
        <<gamma>>, <<gammaf>>, <<lgamma>>, <<lgammaf>>, <<gamma_r>>, <<gammaf_r>>, <<lgamma_r>>, <<lgammaf_r>>, <<tgamma>>, and <<tgammaf>>--logarithmic and plain gamma functions
        <<gamma>>, <<gammaf>>, <<lgamma>>, <<lgammaf>>, <<gamma_r>>, <<gammaf_r>>, <<lgamma_r>>, <<lgammaf_r>>, <<tgamma>>, and <<tgammaf>>--logarithmic and plain gamma functions
 
 
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
INDEX
INDEX
tgamma
tgamma
INDEX
INDEX
tgammaf
tgammaf
 
 
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]>);
double tgamma(double <[x]>);
double tgamma(double <[x]>);
float tgammaf(float <[x]>);
float tgammaf(float <[x]>);
 
 
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]>;
double tgamma(<[x]>)
double tgamma(<[x]>)
double <[x]>;
double <[x]>;
float tgammaf(<[x]>)
float tgammaf(<[x]>)
float <[x]>;
float <[x]>;
 
 
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).
 
 
<<tgamma>> and <<tgammaf>> are the "true gamma" functions, returning
<<tgamma>> and <<tgammaf>> are the "true gamma" functions, returning
@tex
@tex
$\mit \Gamma(x)$,
$\mit \Gamma(x)$,
@end tex
@end tex
the gamma function of <[x]>--without a logarithm.
the gamma function of <[x]>--without a logarithm.
(They are apparently so named because of the prior existence of the old,
(They are apparently so named because of the prior existence of the old,
poorly-named <<gamma>> functions which returned the log of gamma up
poorly-named <<gamma>> functions which returned the log of gamma up
through BSD 4.2.)
through BSD 4.2.)
 
 
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.  It is better not to use either
Neither <<gamma>> nor <<gammaf>> is ANSI C.  It is better not to use either
of these; use <<lgamma>> or <<tgamma>> instead.@*
of these; use <<lgamma>> or <<tgamma>> instead.@*
<<lgamma>>, <<lgammaf>>, <<tgamma>>, and <<tgammaf>> are nominally C standard
<<lgamma>>, <<lgammaf>>, <<tgamma>>, and <<tgammaf>> are nominally C standard
in terms of the base return values, although the <<matherr>> error-handling
in terms of the base return values, although the <<matherr>> error-handling
is not standard, nor is the <[signgam]> global for <<lgamma>>.
is not standard, nor is the <[signgam]> global for <<lgamma>>.
*/
*/
 
 
/* double gamma(double x)
/* double gamma(double x)
 * Return the logarithm of the Gamma function of x.
 * Return the logarithm of the Gamma function of x.
 *
 *
 * Method: call gamma_r
 * Method: call gamma_r
 */
 */
 
 
#include "fdlibm.h"
#include "fdlibm.h"
#include <reent.h>
#include <reent.h>
#include <errno.h>
#include <errno.h>
 
 
#ifndef _DOUBLE_IS_32BITS
#ifndef _DOUBLE_IS_32BITS
 
 
#ifdef __STDC__
#ifdef __STDC__
        double gamma(double x)
        double gamma(double x)
#else
#else
        double gamma(x)
        double gamma(x)
        double x;
        double x;
#endif
#endif
{
{
#ifdef _IEEE_LIBM
#ifdef _IEEE_LIBM
        return __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT)));
        return __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT)));
#else
#else
        double y;
        double y;
        struct exception exc;
        struct exception exc;
        y = __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT)));
        y = __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT)));
        if(_LIB_VERSION == _IEEE_) return y;
        if(_LIB_VERSION == _IEEE_) return y;
        if(!finite(y)&&finite(x)) {
        if(!finite(y)&&finite(x)) {
#ifndef HUGE_VAL 
#ifndef HUGE_VAL 
#define HUGE_VAL inf
#define HUGE_VAL inf
            double inf = 0.0;
            double inf = 0.0;
 
 
            SET_HIGH_WORD(inf,0x7ff00000);      /* set inf to infinite */
            SET_HIGH_WORD(inf,0x7ff00000);      /* set inf to infinite */
#endif
#endif
            exc.name = "gamma";
            exc.name = "gamma";
            exc.err = 0;
            exc.err = 0;
            exc.arg1 = exc.arg2 = x;
            exc.arg1 = exc.arg2 = x;
            if (_LIB_VERSION == _SVID_)
            if (_LIB_VERSION == _SVID_)
                exc.retval = HUGE;
                exc.retval = HUGE;
            else
            else
                exc.retval = HUGE_VAL;
                exc.retval = HUGE_VAL;
            if(floor(x)==x&&x<=0.0) {
            if(floor(x)==x&&x<=0.0) {
                /* gamma(-integer) or gamma(0) */
                /* gamma(-integer) or gamma(0) */
                exc.type = SING;
                exc.type = SING;
                if (_LIB_VERSION == _POSIX_)
                if (_LIB_VERSION == _POSIX_)
                  errno = EDOM;
                  errno = EDOM;
                else if (!matherr(&exc)) {
                else if (!matherr(&exc)) {
                  errno = EDOM;
                  errno = EDOM;
                }
                }
            } else {
            } else {
                /* gamma(finite) overflow */
                /* gamma(finite) overflow */
                exc.type = OVERFLOW;
                exc.type = OVERFLOW;
                if (_LIB_VERSION == _POSIX_)
                if (_LIB_VERSION == _POSIX_)
                  errno = ERANGE;
                  errno = ERANGE;
                else if (!matherr(&exc)) {
                else if (!matherr(&exc)) {
                  errno = ERANGE;
                  errno = ERANGE;
                }
                }
            }
            }
            if (exc.err != 0)
            if (exc.err != 0)
               errno = exc.err;
               errno = exc.err;
            return exc.retval;
            return exc.retval;
        } else
        } else
            return y;
            return y;
#endif
#endif
}
}
 
 
#endif /* defined(_DOUBLE_IS_32BITS) */
#endif /* defined(_DOUBLE_IS_32BITS) */
 
 

powered by: WebSVN 2.1.0

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