Home | History | Annotate | Line # | Download | only in math
powq.c revision 1.1
      1  1.1  mrg /*
      2  1.1  mrg  * ====================================================
      3  1.1  mrg  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
      4  1.1  mrg  *
      5  1.1  mrg  * Developed at SunPro, a Sun Microsystems, Inc. business.
      6  1.1  mrg  * Permission to use, copy, modify, and distribute this
      7  1.1  mrg  * software is freely granted, provided that this notice
      8  1.1  mrg  * is preserved.
      9  1.1  mrg  * ====================================================
     10  1.1  mrg  */
     11  1.1  mrg 
     12  1.1  mrg /* Expansions and modifications for 128-bit long double are
     13  1.1  mrg    Copyright (C) 2001 Stephen L. Moshier <moshier (at) na-net.ornl.gov>
     14  1.1  mrg    and are incorporated herein by permission of the author.  The author
     15  1.1  mrg    reserves the right to distribute this material elsewhere under different
     16  1.1  mrg    copying permissions.  These modifications are distributed here under
     17  1.1  mrg    the following terms:
     18  1.1  mrg 
     19  1.1  mrg     This library is free software; you can redistribute it and/or
     20  1.1  mrg     modify it under the terms of the GNU Lesser General Public
     21  1.1  mrg     License as published by the Free Software Foundation; either
     22  1.1  mrg     version 2.1 of the License, or (at your option) any later version.
     23  1.1  mrg 
     24  1.1  mrg     This library is distributed in the hope that it will be useful,
     25  1.1  mrg     but WITHOUT ANY WARRANTY; without even the implied warranty of
     26  1.1  mrg     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     27  1.1  mrg     Lesser General Public License for more details.
     28  1.1  mrg 
     29  1.1  mrg     You should have received a copy of the GNU Lesser General Public
     30  1.1  mrg     License along with this library; if not, see
     31  1.1  mrg     <http://www.gnu.org/licenses/>.  */
     32  1.1  mrg 
     33  1.1  mrg /* powq(x,y) return x**y
     34  1.1  mrg  *
     35  1.1  mrg  *		      n
     36  1.1  mrg  * Method:  Let x =  2   * (1+f)
     37  1.1  mrg  *	1. Compute and return log2(x) in two pieces:
     38  1.1  mrg  *		log2(x) = w1 + w2,
     39  1.1  mrg  *	   where w1 has 113-53 = 60 bit trailing zeros.
     40  1.1  mrg  *	2. Perform y*log2(x) = n+y' by simulating muti-precision
     41  1.1  mrg  *	   arithmetic, where |y'|<=0.5.
     42  1.1  mrg  *	3. Return x**y = 2**n*exp(y'*log2)
     43  1.1  mrg  *
     44  1.1  mrg  * Special cases:
     45  1.1  mrg  *	1.  (anything) ** 0  is 1
     46  1.1  mrg  *	2.  (anything) ** 1  is itself
     47  1.1  mrg  *	3.  (anything) ** NAN is NAN
     48  1.1  mrg  *	4.  NAN ** (anything except 0) is NAN
     49  1.1  mrg  *	5.  +-(|x| > 1) **  +INF is +INF
     50  1.1  mrg  *	6.  +-(|x| > 1) **  -INF is +0
     51  1.1  mrg  *	7.  +-(|x| < 1) **  +INF is +0
     52  1.1  mrg  *	8.  +-(|x| < 1) **  -INF is +INF
     53  1.1  mrg  *	9.  +-1         ** +-INF is NAN
     54  1.1  mrg  *	10. +0 ** (+anything except 0, NAN)               is +0
     55  1.1  mrg  *	11. -0 ** (+anything except 0, NAN, odd integer)  is +0
     56  1.1  mrg  *	12. +0 ** (-anything except 0, NAN)               is +INF
     57  1.1  mrg  *	13. -0 ** (-anything except 0, NAN, odd integer)  is +INF
     58  1.1  mrg  *	14. -0 ** (odd integer) = -( +0 ** (odd integer) )
     59  1.1  mrg  *	15. +INF ** (+anything except 0,NAN) is +INF
     60  1.1  mrg  *	16. +INF ** (-anything except 0,NAN) is +0
     61  1.1  mrg  *	17. -INF ** (anything)  = -0 ** (-anything)
     62  1.1  mrg  *	18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
     63  1.1  mrg  *	19. (-anything except 0 and inf) ** (non-integer) is NAN
     64  1.1  mrg  *
     65  1.1  mrg  */
     66  1.1  mrg 
     67  1.1  mrg #include "quadmath-imp.h"
     68  1.1  mrg 
     69  1.1  mrg static const __float128 bp[] = {
     70  1.1  mrg   1,
     71  1.1  mrg   1.5Q,
     72  1.1  mrg };
     73  1.1  mrg 
     74  1.1  mrg /* log_2(1.5) */
     75  1.1  mrg static const __float128 dp_h[] = {
     76  1.1  mrg   0.0,
     77  1.1  mrg   5.8496250072115607565592654282227158546448E-1Q
     78  1.1  mrg };
     79  1.1  mrg 
     80  1.1  mrg /* Low part of log_2(1.5) */
     81  1.1  mrg static const __float128 dp_l[] = {
     82  1.1  mrg   0.0,
     83  1.1  mrg   1.0579781240112554492329533686862998106046E-16Q
     84  1.1  mrg };
     85  1.1  mrg 
     86  1.1  mrg static const __float128 zero = 0,
     87  1.1  mrg   one = 1,
     88  1.1  mrg   two = 2,
     89  1.1  mrg   two113 = 1.0384593717069655257060992658440192E34Q,
     90  1.1  mrg   huge = 1.0e3000Q,
     91  1.1  mrg   tiny = 1.0e-3000Q;
     92  1.1  mrg 
     93  1.1  mrg /* 3/2 log x = 3 z + z^3 + z^3 (z^2 R(z^2))
     94  1.1  mrg    z = (x-1)/(x+1)
     95  1.1  mrg    1 <= x <= 1.25
     96  1.1  mrg    Peak relative error 2.3e-37 */
     97  1.1  mrg static const __float128 LN[] =
     98  1.1  mrg {
     99  1.1  mrg  -3.0779177200290054398792536829702930623200E1Q,
    100  1.1  mrg   6.5135778082209159921251824580292116201640E1Q,
    101  1.1  mrg  -4.6312921812152436921591152809994014413540E1Q,
    102  1.1  mrg   1.2510208195629420304615674658258363295208E1Q,
    103  1.1  mrg  -9.9266909031921425609179910128531667336670E-1Q
    104  1.1  mrg };
    105  1.1  mrg static const __float128 LD[] =
    106  1.1  mrg {
    107  1.1  mrg  -5.129862866715009066465422805058933131960E1Q,
    108  1.1  mrg   1.452015077564081884387441590064272782044E2Q,
    109  1.1  mrg  -1.524043275549860505277434040464085593165E2Q,
    110  1.1  mrg   7.236063513651544224319663428634139768808E1Q,
    111  1.1  mrg  -1.494198912340228235853027849917095580053E1Q
    112  1.1  mrg   /* 1.0E0 */
    113  1.1  mrg };
    114  1.1  mrg 
    115  1.1  mrg /* exp(x) = 1 + x - x / (1 - 2 / (x - x^2 R(x^2)))
    116  1.1  mrg    0 <= x <= 0.5
    117  1.1  mrg    Peak relative error 5.7e-38  */
    118  1.1  mrg static const __float128 PN[] =
    119  1.1  mrg {
    120  1.1  mrg   5.081801691915377692446852383385968225675E8Q,
    121  1.1  mrg   9.360895299872484512023336636427675327355E6Q,
    122  1.1  mrg   4.213701282274196030811629773097579432957E4Q,
    123  1.1  mrg   5.201006511142748908655720086041570288182E1Q,
    124  1.1  mrg   9.088368420359444263703202925095675982530E-3Q,
    125  1.1  mrg };
    126  1.1  mrg static const __float128 PD[] =
    127  1.1  mrg {
    128  1.1  mrg   3.049081015149226615468111430031590411682E9Q,
    129  1.1  mrg   1.069833887183886839966085436512368982758E8Q,
    130  1.1  mrg   8.259257717868875207333991924545445705394E5Q,
    131  1.1  mrg   1.872583833284143212651746812884298360922E3Q,
    132  1.1  mrg   /* 1.0E0 */
    133  1.1  mrg };
    134  1.1  mrg 
    135  1.1  mrg static const __float128
    136  1.1  mrg   /* ln 2 */
    137  1.1  mrg   lg2 = 6.9314718055994530941723212145817656807550E-1Q,
    138  1.1  mrg   lg2_h = 6.9314718055994528622676398299518041312695E-1Q,
    139  1.1  mrg   lg2_l = 2.3190468138462996154948554638754786504121E-17Q,
    140  1.1  mrg   ovt = 8.0085662595372944372e-0017Q,
    141  1.1  mrg   /* 2/(3*log(2)) */
    142  1.1  mrg   cp = 9.6179669392597560490661645400126142495110E-1Q,
    143  1.1  mrg   cp_h = 9.6179669392597555432899980587535537779331E-1Q,
    144  1.1  mrg   cp_l = 5.0577616648125906047157785230014751039424E-17Q;
    145  1.1  mrg 
    146  1.1  mrg __float128
    147  1.1  mrg powq (__float128 x, __float128 y)
    148  1.1  mrg {
    149  1.1  mrg   __float128 z, ax, z_h, z_l, p_h, p_l;
    150  1.1  mrg   __float128 y1, t1, t2, r, s, sgn, t, u, v, w;
    151  1.1  mrg   __float128 s2, s_h, s_l, t_h, t_l, ay;
    152  1.1  mrg   int32_t i, j, k, yisint, n;
    153  1.1  mrg   uint32_t ix, iy;
    154  1.1  mrg   int32_t hx, hy;
    155  1.1  mrg   ieee854_float128 o, p, q;
    156  1.1  mrg 
    157  1.1  mrg   p.value = x;
    158  1.1  mrg   hx = p.words32.w0;
    159  1.1  mrg   ix = hx & 0x7fffffff;
    160  1.1  mrg 
    161  1.1  mrg   q.value = y;
    162  1.1  mrg   hy = q.words32.w0;
    163  1.1  mrg   iy = hy & 0x7fffffff;
    164  1.1  mrg 
    165  1.1  mrg 
    166  1.1  mrg   /* y==zero: x**0 = 1 */
    167  1.1  mrg   if ((iy | q.words32.w1 | q.words32.w2 | q.words32.w3) == 0
    168  1.1  mrg       && !issignalingq (x))
    169  1.1  mrg     return one;
    170  1.1  mrg 
    171  1.1  mrg   /* 1.0**y = 1; -1.0**+-Inf = 1 */
    172  1.1  mrg   if (x == one && !issignalingq (y))
    173  1.1  mrg     return one;
    174  1.1  mrg   if (x == -1 && iy == 0x7fff0000
    175  1.1  mrg       && (q.words32.w1 | q.words32.w2 | q.words32.w3) == 0)
    176  1.1  mrg     return one;
    177  1.1  mrg 
    178  1.1  mrg   /* +-NaN return x+y */
    179  1.1  mrg   if ((ix > 0x7fff0000)
    180  1.1  mrg       || ((ix == 0x7fff0000)
    181  1.1  mrg 	  && ((p.words32.w1 | p.words32.w2 | p.words32.w3) != 0))
    182  1.1  mrg       || (iy > 0x7fff0000)
    183  1.1  mrg       || ((iy == 0x7fff0000)
    184  1.1  mrg 	  && ((q.words32.w1 | q.words32.w2 | q.words32.w3) != 0)))
    185  1.1  mrg     return x + y;
    186  1.1  mrg 
    187  1.1  mrg   /* determine if y is an odd int when x < 0
    188  1.1  mrg    * yisint = 0       ... y is not an integer
    189  1.1  mrg    * yisint = 1       ... y is an odd int
    190  1.1  mrg    * yisint = 2       ... y is an even int
    191  1.1  mrg    */
    192  1.1  mrg   yisint = 0;
    193  1.1  mrg   if (hx < 0)
    194  1.1  mrg     {
    195  1.1  mrg       if (iy >= 0x40700000)	/* 2^113 */
    196  1.1  mrg 	yisint = 2;		/* even integer y */
    197  1.1  mrg       else if (iy >= 0x3fff0000)	/* 1.0 */
    198  1.1  mrg 	{
    199  1.1  mrg 	  if (floorq (y) == y)
    200  1.1  mrg 	    {
    201  1.1  mrg 	      z = 0.5 * y;
    202  1.1  mrg 	      if (floorq (z) == z)
    203  1.1  mrg 		yisint = 2;
    204  1.1  mrg 	      else
    205  1.1  mrg 		yisint = 1;
    206  1.1  mrg 	    }
    207  1.1  mrg 	}
    208  1.1  mrg     }
    209  1.1  mrg 
    210  1.1  mrg   /* special value of y */
    211  1.1  mrg   if ((q.words32.w1 | q.words32.w2 | q.words32.w3) == 0)
    212  1.1  mrg     {
    213  1.1  mrg       if (iy == 0x7fff0000)	/* y is +-inf */
    214  1.1  mrg 	{
    215  1.1  mrg 	  if (((ix - 0x3fff0000) | p.words32.w1 | p.words32.w2 | p.words32.w3)
    216  1.1  mrg 	      == 0)
    217  1.1  mrg 	    return y - y;	/* +-1**inf is NaN */
    218  1.1  mrg 	  else if (ix >= 0x3fff0000)	/* (|x|>1)**+-inf = inf,0 */
    219  1.1  mrg 	    return (hy >= 0) ? y : zero;
    220  1.1  mrg 	  else			/* (|x|<1)**-,+inf = inf,0 */
    221  1.1  mrg 	    return (hy < 0) ? -y : zero;
    222  1.1  mrg 	}
    223  1.1  mrg       if (iy == 0x3fff0000)
    224  1.1  mrg 	{			/* y is  +-1 */
    225  1.1  mrg 	  if (hy < 0)
    226  1.1  mrg 	    return one / x;
    227  1.1  mrg 	  else
    228  1.1  mrg 	    return x;
    229  1.1  mrg 	}
    230  1.1  mrg       if (hy == 0x40000000)
    231  1.1  mrg 	return x * x;		/* y is  2 */
    232  1.1  mrg       if (hy == 0x3ffe0000)
    233  1.1  mrg 	{			/* y is  0.5 */
    234  1.1  mrg 	  if (hx >= 0)		/* x >= +0 */
    235  1.1  mrg 	    return sqrtq (x);
    236  1.1  mrg 	}
    237  1.1  mrg     }
    238  1.1  mrg 
    239  1.1  mrg   ax = fabsq (x);
    240  1.1  mrg   /* special value of x */
    241  1.1  mrg   if ((p.words32.w1 | p.words32.w2 | p.words32.w3) == 0)
    242  1.1  mrg     {
    243  1.1  mrg       if (ix == 0x7fff0000 || ix == 0 || ix == 0x3fff0000)
    244  1.1  mrg 	{
    245  1.1  mrg 	  z = ax;		/*x is +-0,+-inf,+-1 */
    246  1.1  mrg 	  if (hy < 0)
    247  1.1  mrg 	    z = one / z;	/* z = (1/|x|) */
    248  1.1  mrg 	  if (hx < 0)
    249  1.1  mrg 	    {
    250  1.1  mrg 	      if (((ix - 0x3fff0000) | yisint) == 0)
    251  1.1  mrg 		{
    252  1.1  mrg 		  z = (z - z) / (z - z);	/* (-1)**non-int is NaN */
    253  1.1  mrg 		}
    254  1.1  mrg 	      else if (yisint == 1)
    255  1.1  mrg 		z = -z;		/* (x<0)**odd = -(|x|**odd) */
    256  1.1  mrg 	    }
    257  1.1  mrg 	  return z;
    258  1.1  mrg 	}
    259  1.1  mrg     }
    260  1.1  mrg 
    261  1.1  mrg   /* (x<0)**(non-int) is NaN */
    262  1.1  mrg   if (((((uint32_t) hx >> 31) - 1) | yisint) == 0)
    263  1.1  mrg     return (x - x) / (x - x);
    264  1.1  mrg 
    265  1.1  mrg   /* sgn (sign of result -ve**odd) = -1 else = 1 */
    266  1.1  mrg   sgn = one;
    267  1.1  mrg   if (((((uint32_t) hx >> 31) - 1) | (yisint - 1)) == 0)
    268  1.1  mrg     sgn = -one;			/* (-ve)**(odd int) */
    269  1.1  mrg 
    270  1.1  mrg   /* |y| is huge.
    271  1.1  mrg      2^-16495 = 1/2 of smallest representable value.
    272  1.1  mrg      If (1 - 1/131072)^y underflows, y > 1.4986e9 */
    273  1.1  mrg   if (iy > 0x401d654b)
    274  1.1  mrg     {
    275  1.1  mrg       /* if (1 - 2^-113)^y underflows, y > 1.1873e38 */
    276  1.1  mrg       if (iy > 0x407d654b)
    277  1.1  mrg 	{
    278  1.1  mrg 	  if (ix <= 0x3ffeffff)
    279  1.1  mrg 	    return (hy < 0) ? huge * huge : tiny * tiny;
    280  1.1  mrg 	  if (ix >= 0x3fff0000)
    281  1.1  mrg 	    return (hy > 0) ? huge * huge : tiny * tiny;
    282  1.1  mrg 	}
    283  1.1  mrg       /* over/underflow if x is not close to one */
    284  1.1  mrg       if (ix < 0x3ffeffff)
    285  1.1  mrg 	return (hy < 0) ? sgn * huge * huge : sgn * tiny * tiny;
    286  1.1  mrg       if (ix > 0x3fff0000)
    287  1.1  mrg 	return (hy > 0) ? sgn * huge * huge : sgn * tiny * tiny;
    288  1.1  mrg     }
    289  1.1  mrg 
    290  1.1  mrg   ay = y > 0 ? y : -y;
    291  1.1  mrg   if (ay < 0x1p-128)
    292  1.1  mrg     y = y < 0 ? -0x1p-128 : 0x1p-128;
    293  1.1  mrg 
    294  1.1  mrg   n = 0;
    295  1.1  mrg   /* take care subnormal number */
    296  1.1  mrg   if (ix < 0x00010000)
    297  1.1  mrg     {
    298  1.1  mrg       ax *= two113;
    299  1.1  mrg       n -= 113;
    300  1.1  mrg       o.value = ax;
    301  1.1  mrg       ix = o.words32.w0;
    302  1.1  mrg     }
    303  1.1  mrg   n += ((ix) >> 16) - 0x3fff;
    304  1.1  mrg   j = ix & 0x0000ffff;
    305  1.1  mrg   /* determine interval */
    306  1.1  mrg   ix = j | 0x3fff0000;		/* normalize ix */
    307  1.1  mrg   if (j <= 0x3988)
    308  1.1  mrg     k = 0;			/* |x|<sqrt(3/2) */
    309  1.1  mrg   else if (j < 0xbb67)
    310  1.1  mrg     k = 1;			/* |x|<sqrt(3)   */
    311  1.1  mrg   else
    312  1.1  mrg     {
    313  1.1  mrg       k = 0;
    314  1.1  mrg       n += 1;
    315  1.1  mrg       ix -= 0x00010000;
    316  1.1  mrg     }
    317  1.1  mrg 
    318  1.1  mrg   o.value = ax;
    319  1.1  mrg   o.words32.w0 = ix;
    320  1.1  mrg   ax = o.value;
    321  1.1  mrg 
    322  1.1  mrg   /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
    323  1.1  mrg   u = ax - bp[k];		/* bp[0]=1.0, bp[1]=1.5 */
    324  1.1  mrg   v = one / (ax + bp[k]);
    325  1.1  mrg   s = u * v;
    326  1.1  mrg   s_h = s;
    327  1.1  mrg 
    328  1.1  mrg   o.value = s_h;
    329  1.1  mrg   o.words32.w3 = 0;
    330  1.1  mrg   o.words32.w2 &= 0xf8000000;
    331  1.1  mrg   s_h = o.value;
    332  1.1  mrg   /* t_h=ax+bp[k] High */
    333  1.1  mrg   t_h = ax + bp[k];
    334  1.1  mrg   o.value = t_h;
    335  1.1  mrg   o.words32.w3 = 0;
    336  1.1  mrg   o.words32.w2 &= 0xf8000000;
    337  1.1  mrg   t_h = o.value;
    338  1.1  mrg   t_l = ax - (t_h - bp[k]);
    339  1.1  mrg   s_l = v * ((u - s_h * t_h) - s_h * t_l);
    340  1.1  mrg   /* compute log(ax) */
    341  1.1  mrg   s2 = s * s;
    342  1.1  mrg   u = LN[0] + s2 * (LN[1] + s2 * (LN[2] + s2 * (LN[3] + s2 * LN[4])));
    343  1.1  mrg   v = LD[0] + s2 * (LD[1] + s2 * (LD[2] + s2 * (LD[3] + s2 * (LD[4] + s2))));
    344  1.1  mrg   r = s2 * s2 * u / v;
    345  1.1  mrg   r += s_l * (s_h + s);
    346  1.1  mrg   s2 = s_h * s_h;
    347  1.1  mrg   t_h = 3.0 + s2 + r;
    348  1.1  mrg   o.value = t_h;
    349  1.1  mrg   o.words32.w3 = 0;
    350  1.1  mrg   o.words32.w2 &= 0xf8000000;
    351  1.1  mrg   t_h = o.value;
    352  1.1  mrg   t_l = r - ((t_h - 3.0) - s2);
    353  1.1  mrg   /* u+v = s*(1+...) */
    354  1.1  mrg   u = s_h * t_h;
    355  1.1  mrg   v = s_l * t_h + t_l * s;
    356  1.1  mrg   /* 2/(3log2)*(s+...) */
    357  1.1  mrg   p_h = u + v;
    358  1.1  mrg   o.value = p_h;
    359  1.1  mrg   o.words32.w3 = 0;
    360  1.1  mrg   o.words32.w2 &= 0xf8000000;
    361  1.1  mrg   p_h = o.value;
    362  1.1  mrg   p_l = v - (p_h - u);
    363  1.1  mrg   z_h = cp_h * p_h;		/* cp_h+cp_l = 2/(3*log2) */
    364  1.1  mrg   z_l = cp_l * p_h + p_l * cp + dp_l[k];
    365  1.1  mrg   /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
    366  1.1  mrg   t = (__float128) n;
    367  1.1  mrg   t1 = (((z_h + z_l) + dp_h[k]) + t);
    368  1.1  mrg   o.value = t1;
    369  1.1  mrg   o.words32.w3 = 0;
    370  1.1  mrg   o.words32.w2 &= 0xf8000000;
    371  1.1  mrg   t1 = o.value;
    372  1.1  mrg   t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
    373  1.1  mrg 
    374  1.1  mrg   /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
    375  1.1  mrg   y1 = y;
    376  1.1  mrg   o.value = y1;
    377  1.1  mrg   o.words32.w3 = 0;
    378  1.1  mrg   o.words32.w2 &= 0xf8000000;
    379  1.1  mrg   y1 = o.value;
    380  1.1  mrg   p_l = (y - y1) * t1 + y * t2;
    381  1.1  mrg   p_h = y1 * t1;
    382  1.1  mrg   z = p_l + p_h;
    383  1.1  mrg   o.value = z;
    384  1.1  mrg   j = o.words32.w0;
    385  1.1  mrg   if (j >= 0x400d0000) /* z >= 16384 */
    386  1.1  mrg     {
    387  1.1  mrg       /* if z > 16384 */
    388  1.1  mrg       if (((j - 0x400d0000) | o.words32.w1 | o.words32.w2 | o.words32.w3) != 0)
    389  1.1  mrg 	return sgn * huge * huge;	/* overflow */
    390  1.1  mrg       else
    391  1.1  mrg 	{
    392  1.1  mrg 	  if (p_l + ovt > z - p_h)
    393  1.1  mrg 	    return sgn * huge * huge;	/* overflow */
    394  1.1  mrg 	}
    395  1.1  mrg     }
    396  1.1  mrg   else if ((j & 0x7fffffff) >= 0x400d01b9)	/* z <= -16495 */
    397  1.1  mrg     {
    398  1.1  mrg       /* z < -16495 */
    399  1.1  mrg       if (((j - 0xc00d01bc) | o.words32.w1 | o.words32.w2 | o.words32.w3)
    400  1.1  mrg 	  != 0)
    401  1.1  mrg 	return sgn * tiny * tiny;	/* underflow */
    402  1.1  mrg       else
    403  1.1  mrg 	{
    404  1.1  mrg 	  if (p_l <= z - p_h)
    405  1.1  mrg 	    return sgn * tiny * tiny;	/* underflow */
    406  1.1  mrg 	}
    407  1.1  mrg     }
    408  1.1  mrg   /* compute 2**(p_h+p_l) */
    409  1.1  mrg   i = j & 0x7fffffff;
    410  1.1  mrg   k = (i >> 16) - 0x3fff;
    411  1.1  mrg   n = 0;
    412  1.1  mrg   if (i > 0x3ffe0000)
    413  1.1  mrg     {				/* if |z| > 0.5, set n = [z+0.5] */
    414  1.1  mrg       n = floorq (z + 0.5Q);
    415  1.1  mrg       t = n;
    416  1.1  mrg       p_h -= t;
    417  1.1  mrg     }
    418  1.1  mrg   t = p_l + p_h;
    419  1.1  mrg   o.value = t;
    420  1.1  mrg   o.words32.w3 = 0;
    421  1.1  mrg   o.words32.w2 &= 0xf8000000;
    422  1.1  mrg   t = o.value;
    423  1.1  mrg   u = t * lg2_h;
    424  1.1  mrg   v = (p_l - (t - p_h)) * lg2 + t * lg2_l;
    425  1.1  mrg   z = u + v;
    426  1.1  mrg   w = v - (z - u);
    427  1.1  mrg   /*  exp(z) */
    428  1.1  mrg   t = z * z;
    429  1.1  mrg   u = PN[0] + t * (PN[1] + t * (PN[2] + t * (PN[3] + t * PN[4])));
    430  1.1  mrg   v = PD[0] + t * (PD[1] + t * (PD[2] + t * (PD[3] + t)));
    431  1.1  mrg   t1 = z - t * u / v;
    432  1.1  mrg   r = (z * t1) / (t1 - two) - (w + z * w);
    433  1.1  mrg   z = one - (r - z);
    434  1.1  mrg   o.value = z;
    435  1.1  mrg   j = o.words32.w0;
    436  1.1  mrg   j += (n << 16);
    437  1.1  mrg   if ((j >> 16) <= 0)
    438  1.1  mrg     {
    439  1.1  mrg       z = scalbnq (z, n);	/* subnormal output */
    440  1.1  mrg       __float128 force_underflow = z * z;
    441  1.1  mrg       math_force_eval (force_underflow);
    442  1.1  mrg     }
    443  1.1  mrg   else
    444  1.1  mrg     {
    445  1.1  mrg       o.words32.w0 = j;
    446  1.1  mrg       z = o.value;
    447  1.1  mrg     }
    448  1.1  mrg   return sgn * z;
    449  1.1  mrg }
    450