#include "mymath.h"

float
alog1p(float xs)
{
    /*
     * (log1p)
     * Return alog(1 + x), taking care to avoid subtraction loss.
     *
     * This version does internal computations in double precision.
     *
     * (17-Jun-2002)
     */

    /* Initialized data */

    static double CUTLO = -0.5;	/* CUTLO = -1/beta, for arbitrary base beta */
    static double CUTHI = 0.5;	/* CUTHI = 1/beta, for arbitrary base beta */
    static double ONE = 1.0;
    static double ZERO = 0.0;

    /* System generated locals */
    float ret_val;

    /* Local variables */
    double
	sum,
	term,
	x,
	xn,
	xtons;

    x = (double)xs;

    /*
     *     We handle the computation in three regions:
     *
     *     x in [-Infinity, CUTLO):  log(1+x)
     *     x in [CUTLO, CUTHI]:      Taylor series
     *     x in (CUTHI, Infinity]:   log(1+x)
     *
     *     The central region suffers loss of ONE or more bits if the
     *     simple formula is used.
     *
     *     We also handle the cases of log1p(NaN) and log1p(0) specially,
     *     so as to preserve NaNs, and the sign of ZERO.
     */

    if (x != x)
	ret_val = xs;
    else if (x == ZERO)
	ret_val = xs;
    else if (x < CUTLO)
	ret_val = (float)log(ONE + x);
    else if (x <= CUTHI)
    {
	term = x;
	sum = ZERO;
	xn = ONE;
	xtons = x;
	while ((sum + term) != sum)
	{
	    sum += term;
	    xn += ONE;
	    xtons = -xtons * x;
	    term = xtons / xn;
	}
	ret_val = (float)sum;
    }
    else
	ret_val = (float)log(ONE + x);

    return (ret_val);
}


float
al1p10(float x)
{
    /* (log1p10) */
    /* Return alog10(1 + x), taking care to avoid subtraction loss. */
    /* (17-Jun-2002) */

    static float LOG10E = 0.43429448190325182765112891891660508229439700580366F;

    return (alog1p(x) * LOG10E);
}
