LOGBFACT 3CW "14 January 2010" "mathcw-1.00"

Table of contents


NAME

logbfactf, logbfact, logbfactl, logbfactw, logbfactq, logbfactll, logbfactdf, logbfactd, logbfactdl, logbfactdll - extended-precision base-beta logarithm of n-factorial

SYNOPSIS

cc [ flags ] -I/usr/local/include file(s) -L/usr/local/lib -lmcw [ ... ]

#include <mathcw.h>

extern float logbfactf (int n, int *pj);

extern double logbfact (int n, int *pj);

extern long double logbfactl (int n, int *pj);

extern __float80 logbfactw (int n, int *pj);

extern __float128 logbfactq (int n, int *pj);

extern long_long_double logbfactll (int n, int *pj);

extern decimal_float logbfactdf (int n, int *pj);

extern decimal_double logbfactd (int n, int *pj);

extern decimal_long_double logbfactdl (int n, int *pj);

extern decimal_long_long_double logbfactdll (int n, int *pj);

NB: Functions with prototypes containing underscores in type names may be available only with certain extended compilers.


DESCRIPTION

Compute an extended-precision base-beta logarithm of the factorial of the first argument: log[beta](n!), where beta is the base (radix) of the floating-point type (usually, 2, 10, or 16).

The result is the sum of an integer and a fraction in [-1/2,1/2], such that the sum represents the logarithm to a few extra digits of precision.

This function makes it possible to compute expressions containing factorials without premature underflow and overflow, and without resorting to the exponential (exp(3CW)) and log-gamma (lgamma(3CW)) functions. That approach introduces large mathematically-unavoidable errors in the computed result when the argument of the exponential is large, because the error magnification of that function is proportional to its argument.

For example, to compute the product x**(-a) * n!, where ** is the power operaor, decompose the expression like this:

m = logb(x) + 1
g = scalbn(x, -m)
x = g * beta**m
f = logbfact(n, &j)
log[beta](n!) = f + j
log[beta](x**(-a)) = -a * log[beta](x)
                    = -a * (m + log[beta](g))
log[beta](x**(-a) * n!) = j + f - a * m - a * log[beta](g)
x**(-a) * n! = beta**(log[beta](x**(-a) * n!)
                    = beta**j * beta**(f - a * m - a * log[beta](g))
                    = scalbn(expbeta(f - a * m - a * log[beta](g)), j)
The expbeta() function here is to be replaced by a base-specific function, such as exp2(3CW), exp10(3CW), or exp16(3CW). Although there is still an exponential function in the final expression, provided that its argument is further reduced exactly to the sum of an integer and a fraction, then that argument is small, and the exponential function error is also expected to be small. The scalbn(3CW) function is exact. The computed result should then be correct to within one or two ulps (units in the last place).

The logbfact(3CW) function family guarantees often-correctly-rounded results for factorials up to (2n)!, where n! is just below the overflow limit, and the results are obtained by fast table lookup, with at worst one logarithm evaluation. For larger arguments, the log-gamma approach is used.


RETURN VALUES

Return the fractional part of the logarithm as the function result in [-1/2,+1/2], and the integer part via the second pointer argument. If that pointer is NULL, the integer part is not stored.

ERRORS

If the first argument is negative, the function result is a quiet NaN, with 0 for the integer returned via the second pointer argument, and with errno set to EDOM.

SEE ALSO

exp2(3CW), exp10(3CW), exp16(3CW), ipow(3CW), lgamma(3CW), pow(3CW), scalbln(3CW), scalbn(3CW), tgamma(3CW).