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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.18.0/] [newlib/] [libm/] [math/] [w_gamma.c] - Blame information for rev 326

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
 
2
/* @(#)w_gamma.c 5.1 93/09/24 */
3
/*
4
 * ====================================================
5
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6
 *
7
 * Developed at SunPro, a Sun Microsystems, Inc. business.
8
 * Permission to use, copy, modify, and distribute this
9
 * software is freely granted, provided that this notice
10
 * is preserved.
11
 * ====================================================
12
 *
13
 */
14
 
15
/* BUG:  FIXME?
16
     According to Linux man pages for tgamma, lgamma, and gamma, the gamma
17
function was originally defined in BSD as implemented here--the log of the gamma
18
function.  BSD 4.3 changed the name to lgamma, apparently removing gamma.  BSD
19
4.4 re-introduced the gamma name with the more intuitive, without logarithm,
20
plain gamma function.  The C99 standard apparently wanted to avoid a problem
21
with the poorly-named earlier gamma and used tgamma when adding a plain
22
gamma function.
23
     So the current gamma is matching an old, bad definition, and not
24
matching a newer, better definition.  */
25
/*
26
FUNCTION
27
        <<gamma>>, <<gammaf>>, <<lgamma>>, <<lgammaf>>, <<gamma_r>>, <<gammaf_r>>, <<lgamma_r>>, <<lgammaf_r>>, <<tgamma>>, and <<tgammaf>>--logarithmic and plain gamma functions
28
 
29
INDEX
30
gamma
31
INDEX
32
gammaf
33
INDEX
34
lgamma
35
INDEX
36
lgammaf
37
INDEX
38
gamma_r
39
INDEX
40
gammaf_r
41
INDEX
42
lgamma_r
43
INDEX
44
lgammaf_r
45
INDEX
46
tgamma
47
INDEX
48
tgammaf
49
 
50
ANSI_SYNOPSIS
51
#include <math.h>
52
double gamma(double <[x]>);
53
float gammaf(float <[x]>);
54
double lgamma(double <[x]>);
55
float lgammaf(float <[x]>);
56
double gamma_r(double <[x]>, int *<[signgamp]>);
57
float gammaf_r(float <[x]>, int *<[signgamp]>);
58
double lgamma_r(double <[x]>, int *<[signgamp]>);
59
float lgammaf_r(float <[x]>, int *<[signgamp]>);
60
double tgamma(double <[x]>);
61
float tgammaf(float <[x]>);
62
 
63
TRAD_SYNOPSIS
64
#include <math.h>
65
double gamma(<[x]>)
66
double <[x]>;
67
float gammaf(<[x]>)
68
float <[x]>;
69
double lgamma(<[x]>)
70
double <[x]>;
71
float lgammaf(<[x]>)
72
float <[x]>;
73
double gamma_r(<[x]>, <[signgamp]>)
74
double <[x]>;
75
int <[signgamp]>;
76
float gammaf_r(<[x]>, <[signgamp]>)
77
float <[x]>;
78
int <[signgamp]>;
79
double lgamma_r(<[x]>, <[signgamp]>)
80
double <[x]>;
81
int <[signgamp]>;
82
float lgammaf_r(<[x]>, <[signgamp]>)
83
float <[x]>;
84
int <[signgamp]>;
85
double tgamma(<[x]>)
86
double <[x]>;
87
float tgammaf(<[x]>)
88
float <[x]>;
89
 
90
DESCRIPTION
91
<<gamma>> calculates
92
@tex
93
$\mit ln\bigl(\Gamma(x)\bigr)$,
94
@end tex
95
the natural logarithm of the gamma function of <[x]>.  The gamma function
96
(<<exp(gamma(<[x]>))>>) is a generalization of factorial, and retains
97
the property that
98
@ifnottex
99
<<exp(gamma(N))>> is equivalent to <<N*exp(gamma(N-1))>>.
100
@end ifnottex
101
@tex
102
$\mit \Gamma(N)\equiv N\times\Gamma(N-1)$.
103
@end tex
104
Accordingly, the results of the gamma function itself grow very
105
quickly.  <<gamma>> is defined as
106
@tex
107
$\mit ln\bigl(\Gamma(x)\bigr)$ rather than simply $\mit \Gamma(x)$
108
@end tex
109
@ifnottex
110
the natural log of the gamma function, rather than the gamma function
111
itself,
112
@end ifnottex
113
to extend the useful range of results representable.
114
 
115
The sign of the result is returned in the global variable <<signgam>>,
116
which is declared in math.h.
117
 
118
<<gammaf>> performs the same calculation as <<gamma>>, but uses and
119
returns <<float>> values.
120
 
121
<<lgamma>> and <<lgammaf>> are alternate names for <<gamma>> and
122
<<gammaf>>.  The use of <<lgamma>> instead of <<gamma>> is a reminder
123
that these functions compute the log of the gamma function, rather
124
than the gamma function itself.
125
 
126
The functions <<gamma_r>>, <<gammaf_r>>, <<lgamma_r>>, and
127
<<lgammaf_r>> are just like <<gamma>>, <<gammaf>>, <<lgamma>>, and
128
<<lgammaf>>, respectively, but take an additional argument.  This
129
additional argument is a pointer to an integer.  This additional
130
argument is used to return the sign of the result, and the global
131
variable <<signgam>> is not used.  These functions may be used for
132
reentrant calls (but they will still set the global variable <<errno>>
133
if an error occurs).
134
 
135
<<tgamma>> and <<tgammaf>> are the "true gamma" functions, returning
136
@tex
137
$\mit \Gamma(x)$,
138
@end tex
139
the gamma function of <[x]>--without a logarithm.
140
(They are apparently so named because of the prior existence of the old,
141
poorly-named <<gamma>> functions which returned the log of gamma up
142
through BSD 4.2.)
143
 
144
RETURNS
145
Normally, the computed result is returned.
146
 
147
When <[x]> is a nonpositive integer, <<gamma>> returns <<HUGE_VAL>>
148
and <<errno>> is set to <<EDOM>>.  If the result overflows, <<gamma>>
149
returns <<HUGE_VAL>> and <<errno>> is set to <<ERANGE>>.
150
 
151
You can modify this error treatment using <<matherr>>.
152
 
153
PORTABILITY
154
Neither <<gamma>> nor <<gammaf>> is ANSI C.  It is better not to use either
155
of these; use <<lgamma>> or <<tgamma>> instead.@*
156
<<lgamma>>, <<lgammaf>>, <<tgamma>>, and <<tgammaf>> are nominally C standard
157
in terms of the base return values, although the <<matherr>> error-handling
158
is not standard, nor is the <[signgam]> global for <<lgamma>>.
159
*/
160
 
161
/* double gamma(double x)
162
 * Return the logarithm of the Gamma function of x.
163
 *
164
 * Method: call gamma_r
165
 */
166
 
167
#include "fdlibm.h"
168
#include <reent.h>
169
#include <errno.h>
170
 
171
#ifndef _DOUBLE_IS_32BITS
172
 
173
#ifdef __STDC__
174
        double gamma(double x)
175
#else
176
        double gamma(x)
177
        double x;
178
#endif
179
{
180
#ifdef _IEEE_LIBM
181
        return __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT)));
182
#else
183
        double y;
184
        struct exception exc;
185
        y = __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT)));
186
        if(_LIB_VERSION == _IEEE_) return y;
187
        if(!finite(y)&&finite(x)) {
188
#ifndef HUGE_VAL 
189
#define HUGE_VAL inf
190
            double inf = 0.0;
191
 
192
            SET_HIGH_WORD(inf,0x7ff00000);      /* set inf to infinite */
193
#endif
194
            exc.name = "gamma";
195
            exc.err = 0;
196
            exc.arg1 = exc.arg2 = x;
197
            if (_LIB_VERSION == _SVID_)
198
                exc.retval = HUGE;
199
            else
200
                exc.retval = HUGE_VAL;
201
            if(floor(x)==x&&x<=0.0) {
202
                /* gamma(-integer) or gamma(0) */
203
                exc.type = SING;
204
                if (_LIB_VERSION == _POSIX_)
205
                  errno = EDOM;
206
                else if (!matherr(&exc)) {
207
                  errno = EDOM;
208
                }
209
            } else {
210
                /* gamma(finite) overflow */
211
                exc.type = OVERFLOW;
212
                if (_LIB_VERSION == _POSIX_)
213
                  errno = ERANGE;
214
                else if (!matherr(&exc)) {
215
                  errno = ERANGE;
216
                }
217
            }
218
            if (exc.err != 0)
219
               errno = exc.err;
220
            return exc.retval;
221
        } else
222
            return y;
223
#endif
224
}
225
 
226
#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.