Blame sysdeps/ieee754/ldbl-128/e_log10l.c

Packit 6c4009
/*							log10l.c
Packit 6c4009
 *
Packit 6c4009
 *	Common logarithm, 128-bit long double precision
Packit 6c4009
 *
Packit 6c4009
 *
Packit 6c4009
 *
Packit 6c4009
 * SYNOPSIS:
Packit 6c4009
 *
Packit 6c4009
 * long double x, y, log10l();
Packit 6c4009
 *
Packit 6c4009
 * y = log10l( x );
Packit 6c4009
 *
Packit 6c4009
 *
Packit 6c4009
 *
Packit 6c4009
 * DESCRIPTION:
Packit 6c4009
 *
Packit 6c4009
 * Returns the base 10 logarithm of x.
Packit 6c4009
 *
Packit 6c4009
 * The argument is separated into its exponent and fractional
Packit 6c4009
 * parts.  If the exponent is between -1 and +1, the logarithm
Packit 6c4009
 * of the fraction is approximated by
Packit 6c4009
 *
Packit 6c4009
 *     log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).
Packit 6c4009
 *
Packit 6c4009
 * Otherwise, setting  z = 2(x-1)/x+1),
Packit 6c4009
 *
Packit 6c4009
 *     log(x) = z + z^3 P(z)/Q(z).
Packit 6c4009
 *
Packit 6c4009
 *
Packit 6c4009
 *
Packit 6c4009
 * ACCURACY:
Packit 6c4009
 *
Packit 6c4009
 *                      Relative error:
Packit 6c4009
 * arithmetic   domain     # trials      peak         rms
Packit 6c4009
 *    IEEE      0.5, 2.0     30000      2.3e-34     4.9e-35
Packit 6c4009
 *    IEEE     exp(+-10000)  30000      1.0e-34     4.1e-35
Packit 6c4009
 *
Packit 6c4009
 * In the tests over the interval exp(+-10000), the logarithms
Packit 6c4009
 * of the random arguments were uniformly distributed over
Packit 6c4009
 * [-10000, +10000].
Packit 6c4009
 *
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
   Cephes Math Library Release 2.2:  January, 1991
Packit 6c4009
   Copyright 1984, 1991 by Stephen L. Moshier
Packit 6c4009
   Adapted for glibc November, 2001
Packit 6c4009
Packit 6c4009
    This library is free software; you can redistribute it and/or
Packit 6c4009
    modify it under the terms of the GNU Lesser General Public
Packit 6c4009
    License as published by the Free Software Foundation; either
Packit 6c4009
    version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
    This library is distributed in the hope that it will be useful,
Packit 6c4009
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
    Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
    You should have received a copy of the GNU Lesser General Public
Packit 6c4009
    License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
#include <math.h>
Packit 6c4009
#include <math_private.h>
Packit 6c4009
Packit 6c4009
/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
Packit 6c4009
 * 1/sqrt(2) <= x < sqrt(2)
Packit 6c4009
 * Theoretical peak relative error = 5.3e-37,
Packit 6c4009
 * relative peak error spread = 2.3e-14
Packit 6c4009
 */
Packit 6c4009
static const _Float128 P[13] =
Packit 6c4009
{
Packit 6c4009
  L(1.313572404063446165910279910527789794488E4),
Packit 6c4009
  L(7.771154681358524243729929227226708890930E4),
Packit 6c4009
  L(2.014652742082537582487669938141683759923E5),
Packit 6c4009
  L(3.007007295140399532324943111654767187848E5),
Packit 6c4009
  L(2.854829159639697837788887080758954924001E5),
Packit 6c4009
  L(1.797628303815655343403735250238293741397E5),
Packit 6c4009
  L(7.594356839258970405033155585486712125861E4),
Packit 6c4009
  L(2.128857716871515081352991964243375186031E4),
Packit 6c4009
  L(3.824952356185897735160588078446136783779E3),
Packit 6c4009
  L(4.114517881637811823002128927449878962058E2),
Packit 6c4009
  L(2.321125933898420063925789532045674660756E1),
Packit 6c4009
  L(4.998469661968096229986658302195402690910E-1),
Packit 6c4009
  L(1.538612243596254322971797716843006400388E-6)
Packit 6c4009
};
Packit 6c4009
static const _Float128 Q[12] =
Packit 6c4009
{
Packit 6c4009
  L(3.940717212190338497730839731583397586124E4),
Packit 6c4009
  L(2.626900195321832660448791748036714883242E5),
Packit 6c4009
  L(7.777690340007566932935753241556479363645E5),
Packit 6c4009
  L(1.347518538384329112529391120390701166528E6),
Packit 6c4009
  L(1.514882452993549494932585972882995548426E6),
Packit 6c4009
  L(1.158019977462989115839826904108208787040E6),
Packit 6c4009
  L(6.132189329546557743179177159925690841200E5),
Packit 6c4009
  L(2.248234257620569139969141618556349415120E5),
Packit 6c4009
  L(5.605842085972455027590989944010492125825E4),
Packit 6c4009
  L(9.147150349299596453976674231612674085381E3),
Packit 6c4009
  L(9.104928120962988414618126155557301584078E2),
Packit 6c4009
  L(4.839208193348159620282142911143429644326E1)
Packit 6c4009
/* 1.000000000000000000000000000000000000000E0L, */
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
Packit 6c4009
 * where z = 2(x-1)/(x+1)
Packit 6c4009
 * 1/sqrt(2) <= x < sqrt(2)
Packit 6c4009
 * Theoretical peak relative error = 1.1e-35,
Packit 6c4009
 * relative peak error spread 1.1e-9
Packit 6c4009
 */
Packit 6c4009
static const _Float128 R[6] =
Packit 6c4009
{
Packit 6c4009
  L(1.418134209872192732479751274970992665513E5),
Packit 6c4009
 L(-8.977257995689735303686582344659576526998E4),
Packit 6c4009
  L(2.048819892795278657810231591630928516206E4),
Packit 6c4009
 L(-2.024301798136027039250415126250455056397E3),
Packit 6c4009
  L(8.057002716646055371965756206836056074715E1),
Packit 6c4009
 L(-8.828896441624934385266096344596648080902E-1)
Packit 6c4009
};
Packit 6c4009
static const _Float128 S[6] =
Packit 6c4009
{
Packit 6c4009
  L(1.701761051846631278975701529965589676574E6),
Packit 6c4009
 L(-1.332535117259762928288745111081235577029E6),
Packit 6c4009
  L(4.001557694070773974936904547424676279307E5),
Packit 6c4009
 L(-5.748542087379434595104154610899551484314E4),
Packit 6c4009
  L(3.998526750980007367835804959888064681098E3),
Packit 6c4009
 L(-1.186359407982897997337150403816839480438E2)
Packit 6c4009
/* 1.000000000000000000000000000000000000000E0L, */
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
static const _Float128
Packit 6c4009
/* log10(2) */
Packit 6c4009
L102A = L(0.3125),
Packit 6c4009
L102B = L(-1.14700043360188047862611052755069732318101185E-2),
Packit 6c4009
/* log10(e) */
Packit 6c4009
L10EA = L(0.5),
Packit 6c4009
L10EB = L(-6.570551809674817234887108108339491770560299E-2),
Packit 6c4009
/* sqrt(2)/2 */
Packit 6c4009
SQRTH = L(7.071067811865475244008443621048490392848359E-1);
Packit 6c4009
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Evaluate P[n] x^n  +  P[n-1] x^(n-1)  +  ...  +  P[0] */
Packit 6c4009
Packit 6c4009
static _Float128
Packit 6c4009
neval (_Float128 x, const _Float128 *p, int n)
Packit 6c4009
{
Packit 6c4009
  _Float128 y;
Packit 6c4009
Packit 6c4009
  p += n;
Packit 6c4009
  y = *p--;
Packit 6c4009
  do
Packit 6c4009
    {
Packit 6c4009
      y = y * x + *p--;
Packit 6c4009
    }
Packit 6c4009
  while (--n > 0);
Packit 6c4009
  return y;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Evaluate x^n+1  +  P[n] x^(n)  +  P[n-1] x^(n-1)  +  ...  +  P[0] */
Packit 6c4009
Packit 6c4009
static _Float128
Packit 6c4009
deval (_Float128 x, const _Float128 *p, int n)
Packit 6c4009
{
Packit 6c4009
  _Float128 y;
Packit 6c4009
Packit 6c4009
  p += n;
Packit 6c4009
  y = x + *p--;
Packit 6c4009
  do
Packit 6c4009
    {
Packit 6c4009
      y = y * x + *p--;
Packit 6c4009
    }
Packit 6c4009
  while (--n > 0);
Packit 6c4009
  return y;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
Packit 6c4009
_Float128
Packit 6c4009
__ieee754_log10l (_Float128 x)
Packit 6c4009
{
Packit 6c4009
  _Float128 z;
Packit 6c4009
  _Float128 y;
Packit 6c4009
  int e;
Packit 6c4009
  int64_t hx, lx;
Packit 6c4009
Packit 6c4009
/* Test for domain */
Packit 6c4009
  GET_LDOUBLE_WORDS64 (hx, lx, x);
Packit 6c4009
  if (((hx & 0x7fffffffffffffffLL) | lx) == 0)
Packit 6c4009
    return (-1 / fabsl (x));		/* log10l(+-0)=-inf  */
Packit 6c4009
  if (hx < 0)
Packit 6c4009
    return (x - x) / (x - x);
Packit 6c4009
  if (hx >= 0x7fff000000000000LL)
Packit 6c4009
    return (x + x);
Packit 6c4009
Packit 6c4009
  if (x == 1)
Packit 6c4009
    return 0;
Packit 6c4009
Packit 6c4009
/* separate mantissa from exponent */
Packit 6c4009
Packit 6c4009
/* Note, frexp is used so that denormal numbers
Packit 6c4009
 * will be handled properly.
Packit 6c4009
 */
Packit 6c4009
  x = __frexpl (x, &e);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* logarithm using log(x) = z + z**3 P(z)/Q(z),
Packit 6c4009
 * where z = 2(x-1)/x+1)
Packit 6c4009
 */
Packit 6c4009
  if ((e > 2) || (e < -2))
Packit 6c4009
    {
Packit 6c4009
      if (x < SQRTH)
Packit 6c4009
	{			/* 2( 2x-1 )/( 2x+1 ) */
Packit 6c4009
	  e -= 1;
Packit 6c4009
	  z = x - L(0.5);
Packit 6c4009
	  y = L(0.5) * z + L(0.5);
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	{			/*  2 (x-1)/(x+1)   */
Packit 6c4009
	  z = x - L(0.5);
Packit 6c4009
	  z -= L(0.5);
Packit 6c4009
	  y = L(0.5) * x + L(0.5);
Packit 6c4009
	}
Packit 6c4009
      x = z / y;
Packit 6c4009
      z = x * x;
Packit 6c4009
      y = x * (z * neval (z, R, 5) / deval (z, S, 5));
Packit 6c4009
      goto done;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
Packit 6c4009
Packit 6c4009
  if (x < SQRTH)
Packit 6c4009
    {
Packit 6c4009
      e -= 1;
Packit 6c4009
      x = 2.0 * x - 1;	/*  2x - 1  */
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      x = x - 1;
Packit 6c4009
    }
Packit 6c4009
  z = x * x;
Packit 6c4009
  y = x * (z * neval (x, P, 12) / deval (x, Q, 11));
Packit 6c4009
  y = y - 0.5 * z;
Packit 6c4009
Packit 6c4009
done:
Packit 6c4009
Packit 6c4009
  /* Multiply log of fraction by log10(e)
Packit 6c4009
   * and base 2 exponent by log10(2).
Packit 6c4009
   */
Packit 6c4009
  z = y * L10EB;
Packit 6c4009
  z += x * L10EB;
Packit 6c4009
  z += e * L102B;
Packit 6c4009
  z += y * L10EA;
Packit 6c4009
  z += x * L10EA;
Packit 6c4009
  z += e * L102A;
Packit 6c4009
  return (z);
Packit 6c4009
}
Packit 6c4009
strong_alias (__ieee754_log10l, __log10l_finite)