Blame sysdeps/ieee754/ldbl-128ibm/e_logl.c

Packit Service 82fcde
/*							logll.c
Packit Service 82fcde
 *
Packit Service 82fcde
 * Natural logarithm for 128-bit long double precision.
Packit Service 82fcde
 *
Packit Service 82fcde
 *
Packit Service 82fcde
 *
Packit Service 82fcde
 * SYNOPSIS:
Packit Service 82fcde
 *
Packit Service 82fcde
 * long double x, y, logl();
Packit Service 82fcde
 *
Packit Service 82fcde
 * y = logl( x );
Packit Service 82fcde
 *
Packit Service 82fcde
 *
Packit Service 82fcde
 *
Packit Service 82fcde
 * DESCRIPTION:
Packit Service 82fcde
 *
Packit Service 82fcde
 * Returns the base e (2.718...) logarithm of x.
Packit Service 82fcde
 *
Packit Service 82fcde
 * The argument is separated into its exponent and fractional
Packit Service 82fcde
 * parts.  Use of a lookup table increases the speed of the routine.
Packit Service 82fcde
 * The program uses logarithms tabulated at intervals of 1/128 to
Packit Service 82fcde
 * cover the domain from approximately 0.7 to 1.4.
Packit Service 82fcde
 *
Packit Service 82fcde
 * On the interval [-1/128, +1/128] the logarithm of 1+x is approximated by
Packit Service 82fcde
 *     log(1+x) = x - 0.5 x^2 + x^3 P(x) .
Packit Service 82fcde
 *
Packit Service 82fcde
 *
Packit Service 82fcde
 *
Packit Service 82fcde
 * ACCURACY:
Packit Service 82fcde
 *
Packit Service 82fcde
 *                      Relative error:
Packit Service 82fcde
 * arithmetic   domain     # trials      peak         rms
Packit Service 82fcde
 *    IEEE   0.875, 1.125   100000      1.2e-34    4.1e-35
Packit Service 82fcde
 *    IEEE   0.125, 8       100000      1.2e-34    4.1e-35
Packit Service 82fcde
 *
Packit Service 82fcde
 *
Packit Service 82fcde
 * WARNING:
Packit Service 82fcde
 *
Packit Service 82fcde
 * This program uses integer operations on bit fields of floating-point
Packit Service 82fcde
 * numbers.  It does not work with data structures other than the
Packit Service 82fcde
 * structure assumed.
Packit Service 82fcde
 *
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
/* Copyright 2001 by Stephen L. Moshier <moshier@na-net.ornl.gov>
Packit Service 82fcde
Packit Service 82fcde
    This library is free software; you can redistribute it and/or
Packit Service 82fcde
    modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
    License as published by the Free Software Foundation; either
Packit Service 82fcde
    version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
    This library is distributed in the hope that it will be useful,
Packit Service 82fcde
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
    Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
    You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
    License along with this library; if not, see
Packit Service 82fcde
    <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <math.h>
Packit Service 82fcde
#include <math_private.h>
Packit Service 82fcde
Packit Service 82fcde
/* log(1+x) = x - .5 x^2 + x^3 l(x)
Packit Service 82fcde
   -.0078125 <= x <= +.0078125
Packit Service 82fcde
   peak relative error 1.2e-37 */
Packit Service 82fcde
static const long double
Packit Service 82fcde
l3 =   3.333333333333333333333333333333336096926E-1L,
Packit Service 82fcde
l4 =  -2.499999999999999999999999999486853077002E-1L,
Packit Service 82fcde
l5 =   1.999999999999999999999999998515277861905E-1L,
Packit Service 82fcde
l6 =  -1.666666666666666666666798448356171665678E-1L,
Packit Service 82fcde
l7 =   1.428571428571428571428808945895490721564E-1L,
Packit Service 82fcde
l8 =  -1.249999999999999987884655626377588149000E-1L,
Packit Service 82fcde
l9 =   1.111111111111111093947834982832456459186E-1L,
Packit Service 82fcde
l10 = -1.000000000000532974938900317952530453248E-1L,
Packit Service 82fcde
l11 =  9.090909090915566247008015301349979892689E-2L,
Packit Service 82fcde
l12 = -8.333333211818065121250921925397567745734E-2L,
Packit Service 82fcde
l13 =  7.692307559897661630807048686258659316091E-2L,
Packit Service 82fcde
l14 = -7.144242754190814657241902218399056829264E-2L,
Packit Service 82fcde
l15 =  6.668057591071739754844678883223432347481E-2L;
Packit Service 82fcde
Packit Service 82fcde
/* Lookup table of ln(t) - (t-1)
Packit Service 82fcde
    t = 0.5 + (k+26)/128)
Packit Service 82fcde
    k = 0, ..., 91   */
Packit Service 82fcde
static const long double logtbl[92] = {
Packit Service 82fcde
-5.5345593589352099112142921677820359632418E-2L,
Packit Service 82fcde
-5.2108257402767124761784665198737642086148E-2L,
Packit Service 82fcde
-4.8991686870576856279407775480686721935120E-2L,
Packit Service 82fcde
-4.5993270766361228596215288742353061431071E-2L,
Packit Service 82fcde
-4.3110481649613269682442058976885699556950E-2L,
Packit Service 82fcde
-4.0340872319076331310838085093194799765520E-2L,
Packit Service 82fcde
-3.7682072451780927439219005993827431503510E-2L,
Packit Service 82fcde
-3.5131785416234343803903228503274262719586E-2L,
Packit Service 82fcde
-3.2687785249045246292687241862699949178831E-2L,
Packit Service 82fcde
-3.0347913785027239068190798397055267411813E-2L,
Packit Service 82fcde
-2.8110077931525797884641940838507561326298E-2L,
Packit Service 82fcde
-2.5972247078357715036426583294246819637618E-2L,
Packit Service 82fcde
-2.3932450635346084858612873953407168217307E-2L,
Packit Service 82fcde
-2.1988775689981395152022535153795155900240E-2L,
Packit Service 82fcde
-2.0139364778244501615441044267387667496733E-2L,
Packit Service 82fcde
-1.8382413762093794819267536615342902718324E-2L,
Packit Service 82fcde
-1.6716169807550022358923589720001638093023E-2L,
Packit Service 82fcde
-1.5138929457710992616226033183958974965355E-2L,
Packit Service 82fcde
-1.3649036795397472900424896523305726435029E-2L,
Packit Service 82fcde
-1.2244881690473465543308397998034325468152E-2L,
Packit Service 82fcde
-1.0924898127200937840689817557742469105693E-2L,
Packit Service 82fcde
-9.6875626072830301572839422532631079809328E-3L,
Packit Service 82fcde
-8.5313926245226231463436209313499745894157E-3L,
Packit Service 82fcde
-7.4549452072765973384933565912143044991706E-3L,
Packit Service 82fcde
-6.4568155251217050991200599386801665681310E-3L,
Packit Service 82fcde
-5.5356355563671005131126851708522185605193E-3L,
Packit Service 82fcde
-4.6900728132525199028885749289712348829878E-3L,
Packit Service 82fcde
-3.9188291218610470766469347968659624282519E-3L,
Packit Service 82fcde
-3.2206394539524058873423550293617843896540E-3L,
Packit Service 82fcde
-2.5942708080877805657374888909297113032132E-3L,
Packit Service 82fcde
-2.0385211375711716729239156839929281289086E-3L,
Packit Service 82fcde
-1.5522183228760777967376942769773768850872E-3L,
Packit Service 82fcde
-1.1342191863606077520036253234446621373191E-3L,
Packit Service 82fcde
-7.8340854719967065861624024730268350459991E-4L,
Packit Service 82fcde
-4.9869831458030115699628274852562992756174E-4L,
Packit Service 82fcde
-2.7902661731604211834685052867305795169688E-4L,
Packit Service 82fcde
-1.2335696813916860754951146082826952093496E-4L,
Packit Service 82fcde
-3.0677461025892873184042490943581654591817E-5L,
Packit Service 82fcde
#define ZERO logtbl[38]
Packit Service 82fcde
 0.0000000000000000000000000000000000000000E0L,
Packit Service 82fcde
-3.0359557945051052537099938863236321874198E-5L,
Packit Service 82fcde
-1.2081346403474584914595395755316412213151E-4L,
Packit Service 82fcde
-2.7044071846562177120083903771008342059094E-4L,
Packit Service 82fcde
-4.7834133324631162897179240322783590830326E-4L,
Packit Service 82fcde
-7.4363569786340080624467487620270965403695E-4L,
Packit Service 82fcde
-1.0654639687057968333207323853366578860679E-3L,
Packit Service 82fcde
-1.4429854811877171341298062134712230604279E-3L,
Packit Service 82fcde
-1.8753781835651574193938679595797367137975E-3L,
Packit Service 82fcde
-2.3618380914922506054347222273705859653658E-3L,
Packit Service 82fcde
-2.9015787624124743013946600163375853631299E-3L,
Packit Service 82fcde
-3.4938307889254087318399313316921940859043E-3L,
Packit Service 82fcde
-4.1378413103128673800485306215154712148146E-3L,
Packit Service 82fcde
-4.8328735414488877044289435125365629849599E-3L,
Packit Service 82fcde
-5.5782063183564351739381962360253116934243E-3L,
Packit Service 82fcde
-6.3731336597098858051938306767880719015261E-3L,
Packit Service 82fcde
-7.2169643436165454612058905294782949315193E-3L,
Packit Service 82fcde
-8.1090214990427641365934846191367315083867E-3L,
Packit Service 82fcde
-9.0486422112807274112838713105168375482480E-3L,
Packit Service 82fcde
-1.0035177140880864314674126398350812606841E-2L,
Packit Service 82fcde
-1.1067990155502102718064936259435676477423E-2L,
Packit Service 82fcde
-1.2146457974158024928196575103115488672416E-2L,
Packit Service 82fcde
-1.3269969823361415906628825374158424754308E-2L,
Packit Service 82fcde
-1.4437927104692837124388550722759686270765E-2L,
Packit Service 82fcde
-1.5649743073340777659901053944852735064621E-2L,
Packit Service 82fcde
-1.6904842527181702880599758489058031645317E-2L,
Packit Service 82fcde
-1.8202661505988007336096407340750378994209E-2L,
Packit Service 82fcde
-1.9542647000370545390701192438691126552961E-2L,
Packit Service 82fcde
-2.0924256670080119637427928803038530924742E-2L,
Packit Service 82fcde
-2.2346958571309108496179613803760727786257E-2L,
Packit Service 82fcde
-2.3810230892650362330447187267648486279460E-2L,
Packit Service 82fcde
-2.5313561699385640380910474255652501521033E-2L,
Packit Service 82fcde
-2.6856448685790244233704909690165496625399E-2L,
Packit Service 82fcde
-2.8438398935154170008519274953860128449036E-2L,
Packit Service 82fcde
-3.0058928687233090922411781058956589863039E-2L,
Packit Service 82fcde
-3.1717563112854831855692484086486099896614E-2L,
Packit Service 82fcde
-3.3413836095418743219397234253475252001090E-2L,
Packit Service 82fcde
-3.5147290019036555862676702093393332533702E-2L,
Packit Service 82fcde
-3.6917475563073933027920505457688955423688E-2L,
Packit Service 82fcde
-3.8723951502862058660874073462456610731178E-2L,
Packit Service 82fcde
-4.0566284516358241168330505467000838017425E-2L,
Packit Service 82fcde
-4.2444048996543693813649967076598766917965E-2L,
Packit Service 82fcde
-4.4356826869355401653098777649745233339196E-2L,
Packit Service 82fcde
-4.6304207416957323121106944474331029996141E-2L,
Packit Service 82fcde
-4.8285787106164123613318093945035804818364E-2L,
Packit Service 82fcde
-5.0301169421838218987124461766244507342648E-2L,
Packit Service 82fcde
-5.2349964705088137924875459464622098310997E-2L,
Packit Service 82fcde
-5.4431789996103111613753440311680967840214E-2L,
Packit Service 82fcde
-5.6546268881465384189752786409400404404794E-2L,
Packit Service 82fcde
-5.8693031345788023909329239565012647817664E-2L,
Packit Service 82fcde
-6.0871713627532018185577188079210189048340E-2L,
Packit Service 82fcde
-6.3081958078862169742820420185833800925568E-2L,
Packit Service 82fcde
-6.5323413029406789694910800219643791556918E-2L,
Packit Service 82fcde
-6.7595732653791419081537811574227049288168E-2L
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
/* ln(2) = ln2a + ln2b with extended precision. */
Packit Service 82fcde
static const long double
Packit Service 82fcde
  ln2a = 6.93145751953125e-1L,
Packit Service 82fcde
  ln2b = 1.4286068203094172321214581765680755001344E-6L;
Packit Service 82fcde
Packit Service 82fcde
static const long double
Packit Service 82fcde
  ldbl_epsilon = 0x1p-106L;
Packit Service 82fcde
Packit Service 82fcde
long double
Packit Service 82fcde
__ieee754_logl(long double x)
Packit Service 82fcde
{
Packit Service 82fcde
  long double z, y, w, t;
Packit Service 82fcde
  unsigned int m;
Packit Service 82fcde
  int k, e;
Packit Service 82fcde
  double xhi;
Packit Service 82fcde
  uint32_t hx, lx;
Packit Service 82fcde
Packit Service 82fcde
  xhi = ldbl_high (x);
Packit Service 82fcde
  EXTRACT_WORDS (hx, lx, xhi);
Packit Service 82fcde
  m = hx;
Packit Service 82fcde
Packit Service 82fcde
  /* Check for IEEE special cases.  */
Packit Service 82fcde
  k = m & 0x7fffffff;
Packit Service 82fcde
  /* log(0) = -infinity. */
Packit Service 82fcde
  if ((k | lx) == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      return -0.5L / ZERO;
Packit Service 82fcde
    }
Packit Service 82fcde
  /* log ( x < 0 ) = NaN */
Packit Service 82fcde
  if (m & 0x80000000)
Packit Service 82fcde
    {
Packit Service 82fcde
      return (x - x) / ZERO;
Packit Service 82fcde
    }
Packit Service 82fcde
  /* log (infinity or NaN) */
Packit Service 82fcde
  if (k >= 0x7ff00000)
Packit Service 82fcde
    {
Packit Service 82fcde
      return x + x;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* On this interval the table is not used due to cancellation error.  */
Packit Service 82fcde
  if ((x <= 1.0078125L) && (x >= 0.9921875L))
Packit Service 82fcde
    {
Packit Service 82fcde
      if (x == 1.0L)
Packit Service 82fcde
	return 0.0L;
Packit Service 82fcde
      z = x - 1.0L;
Packit Service 82fcde
      k = 64;
Packit Service 82fcde
      t = 1.0L;
Packit Service 82fcde
      e = 0;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Extract exponent and reduce domain to 0.703125 <= u < 1.40625  */
Packit Service 82fcde
      unsigned int w0;
Packit Service 82fcde
      e = (int) (m >> 20) - (int) 0x3fe;
Packit Service 82fcde
      if (e == -1022)
Packit Service 82fcde
	{
Packit Service 82fcde
	  x *= 0x1p106L;
Packit Service 82fcde
	  xhi = ldbl_high (x);
Packit Service 82fcde
	  EXTRACT_WORDS (hx, lx, xhi);
Packit Service 82fcde
	  m = hx;
Packit Service 82fcde
	  e = (int) (m >> 20) - (int) 0x3fe - 106;
Packit Service 82fcde
	}
Packit Service 82fcde
      m &= 0xfffff;
Packit Service 82fcde
      w0 = m | 0x3fe00000;
Packit Service 82fcde
      m |= 0x100000;
Packit Service 82fcde
      /* Find lookup table index k from high order bits of the significand. */
Packit Service 82fcde
      if (m < 0x168000)
Packit Service 82fcde
	{
Packit Service 82fcde
	  k = (m - 0xff000) >> 13;
Packit Service 82fcde
	  /* t is the argument 0.5 + (k+26)/128
Packit Service 82fcde
	     of the nearest item to u in the lookup table.  */
Packit Service 82fcde
	  INSERT_WORDS (xhi, 0x3ff00000 + (k << 13), 0);
Packit Service 82fcde
	  t = xhi;
Packit Service 82fcde
	  w0 += 0x100000;
Packit Service 82fcde
	  e -= 1;
Packit Service 82fcde
	  k += 64;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  k = (m - 0xfe000) >> 14;
Packit Service 82fcde
	  INSERT_WORDS (xhi, 0x3fe00000 + (k << 14), 0);
Packit Service 82fcde
	  t = xhi;
Packit Service 82fcde
	}
Packit Service 82fcde
      x = __scalbnl (x, ((int) ((w0 - hx) * 2)) >> 21);
Packit Service 82fcde
      /* log(u) = log( t u/t ) = log(t) + log(u/t)
Packit Service 82fcde
	 log(t) is tabulated in the lookup table.
Packit Service 82fcde
	 Express log(u/t) = log(1+z),  where z = u/t - 1 = (u-t)/t.
Packit Service 82fcde
	 cf. Cody & Waite. */
Packit Service 82fcde
      z = (x - t) / t;
Packit Service 82fcde
    }
Packit Service 82fcde
  /* Series expansion of log(1+z).  */
Packit Service 82fcde
  w = z * z;
Packit Service 82fcde
  /* Avoid spurious underflows.  */
Packit Service 82fcde
  if (__glibc_unlikely (fabsl (z) <= ldbl_epsilon))
Packit Service 82fcde
    y = 0.0L;
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      y = ((((((((((((l15 * z
Packit Service 82fcde
		  + l14) * z
Packit Service 82fcde
		 + l13) * z
Packit Service 82fcde
		+ l12) * z
Packit Service 82fcde
	       + l11) * z
Packit Service 82fcde
	      + l10) * z
Packit Service 82fcde
	     + l9) * z
Packit Service 82fcde
	    + l8) * z
Packit Service 82fcde
	   + l7) * z
Packit Service 82fcde
	  + l6) * z
Packit Service 82fcde
	 + l5) * z
Packit Service 82fcde
	+ l4) * z
Packit Service 82fcde
       + l3) * z * w;
Packit Service 82fcde
      y -= 0.5 * w;
Packit Service 82fcde
    }
Packit Service 82fcde
  y += e * ln2b;  /* Base 2 exponent offset times ln(2).  */
Packit Service 82fcde
  y += z;
Packit Service 82fcde
  y += logtbl[k-26]; /* log(t) - (t-1) */
Packit Service 82fcde
  y += (t - 1.0L);
Packit Service 82fcde
  y += e * ln2a;
Packit Service 82fcde
  return y;
Packit Service 82fcde
}
Packit Service 82fcde
strong_alias (__ieee754_logl, __logl_finite)