Blame sysdeps/ieee754/ldbl-96/s_erfl.c

Packit 6c4009
/*
Packit 6c4009
 * ====================================================
Packit 6c4009
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Packit 6c4009
 *
Packit 6c4009
 * Developed at SunPro, a Sun Microsystems, Inc. business.
Packit 6c4009
 * Permission to use, copy, modify, and distribute this
Packit 6c4009
 * software is freely granted, provided that this notice
Packit 6c4009
 * is preserved.
Packit 6c4009
 * ====================================================
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
/* Long double expansions are
Packit 6c4009
  Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
Packit 6c4009
  and are incorporated herein by permission of the author.  The author
Packit 6c4009
  reserves the right to distribute this material elsewhere under different
Packit 6c4009
  copying permissions.  These modifications are distributed here under
Packit 6c4009
  the following terms:
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
Packit 6c4009
    <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
/* double erf(double x)
Packit 6c4009
 * double erfc(double x)
Packit 6c4009
 *			     x
Packit 6c4009
 *		      2      |\
Packit 6c4009
 *     erf(x)  =  ---------  | exp(-t*t)dt
Packit 6c4009
 *		   sqrt(pi) \|
Packit 6c4009
 *			     0
Packit 6c4009
 *
Packit 6c4009
 *     erfc(x) =  1-erf(x)
Packit 6c4009
 *  Note that
Packit 6c4009
 *		erf(-x) = -erf(x)
Packit 6c4009
 *		erfc(-x) = 2 - erfc(x)
Packit 6c4009
 *
Packit 6c4009
 * Method:
Packit 6c4009
 *	1. For |x| in [0, 0.84375]
Packit 6c4009
 *	    erf(x)  = x + x*R(x^2)
Packit 6c4009
 *          erfc(x) = 1 - erf(x)           if x in [-.84375,0.25]
Packit 6c4009
 *                  = 0.5 + ((0.5-x)-x*R)  if x in [0.25,0.84375]
Packit 6c4009
 *	   Remark. The formula is derived by noting
Packit 6c4009
 *          erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
Packit 6c4009
 *	   and that
Packit 6c4009
 *          2/sqrt(pi) = 1.128379167095512573896158903121545171688
Packit 6c4009
 *	   is close to one. The interval is chosen because the fix
Packit 6c4009
 *	   point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
Packit 6c4009
 *	   near 0.6174), and by some experiment, 0.84375 is chosen to
Packit 6c4009
 *	   guarantee the error is less than one ulp for erf.
Packit 6c4009
 *
Packit 6c4009
 *      2. For |x| in [0.84375,1.25], let s = |x| - 1, and
Packit 6c4009
 *         c = 0.84506291151 rounded to single (24 bits)
Packit 6c4009
 *	erf(x)  = sign(x) * (c  + P1(s)/Q1(s))
Packit 6c4009
 *	erfc(x) = (1-c)  - P1(s)/Q1(s) if x > 0
Packit 6c4009
 *			  1+(c+P1(s)/Q1(s))    if x < 0
Packit 6c4009
 *	   Remark: here we use the taylor series expansion at x=1.
Packit 6c4009
 *		erf(1+s) = erf(1) + s*Poly(s)
Packit 6c4009
 *			 = 0.845.. + P1(s)/Q1(s)
Packit 6c4009
 *	   Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
Packit 6c4009
 *
Packit 6c4009
 *      3. For x in [1.25,1/0.35(~2.857143)],
Packit 6c4009
 *	erfc(x) = (1/x)*exp(-x*x-0.5625+R1(z)/S1(z))
Packit 6c4009
 *              z=1/x^2
Packit 6c4009
 *	erf(x)  = 1 - erfc(x)
Packit 6c4009
 *
Packit 6c4009
 *      4. For x in [1/0.35,107]
Packit 6c4009
 *	erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
Packit 6c4009
 *			= 2.0 - (1/x)*exp(-x*x-0.5625+R2(z)/S2(z))
Packit 6c4009
 *                             if -6.666
Packit 6c4009
 *			= 2.0 - tiny		(if x <= -6.666)
Packit 6c4009
 *              z=1/x^2
Packit 6c4009
 *	erf(x)  = sign(x)*(1.0 - erfc(x)) if x < 6.666, else
Packit 6c4009
 *	erf(x)  = sign(x)*(1.0 - tiny)
Packit 6c4009
 *      Note1:
Packit 6c4009
 *	   To compute exp(-x*x-0.5625+R/S), let s be a single
Packit 6c4009
 *	   precision number and s := x; then
Packit 6c4009
 *		-x*x = -s*s + (s-x)*(s+x)
Packit 6c4009
 *	        exp(-x*x-0.5626+R/S) =
Packit 6c4009
 *			exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
Packit 6c4009
 *      Note2:
Packit 6c4009
 *	   Here 4 and 5 make use of the asymptotic series
Packit 6c4009
 *			  exp(-x*x)
Packit 6c4009
 *		erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
Packit 6c4009
 *			  x*sqrt(pi)
Packit 6c4009
 *
Packit 6c4009
 *      5. For inf > x >= 107
Packit 6c4009
 *	erf(x)  = sign(x) *(1 - tiny)  (raise inexact)
Packit 6c4009
 *	erfc(x) = tiny*tiny (raise underflow) if x > 0
Packit 6c4009
 *			= 2 - tiny if x<0
Packit 6c4009
 *
Packit 6c4009
 *      7. Special case:
Packit 6c4009
 *	erf(0)  = 0, erf(inf)  = 1, erf(-inf) = -1,
Packit 6c4009
 *	erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
Packit 6c4009
 *		erfc/erf(NaN) is NaN
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
Packit 6c4009
#include <errno.h>
Packit 6c4009
#include <float.h>
Packit 6c4009
#include <math.h>
Packit 6c4009
#include <math_private.h>
Packit 6c4009
#include <math-underflow.h>
Packit 6c4009
#include <libm-alias-ldouble.h>
Packit 6c4009
Packit 6c4009
static const long double
Packit 6c4009
tiny = 1e-4931L,
Packit 6c4009
  half = 0.5L,
Packit 6c4009
  one = 1.0L,
Packit 6c4009
  two = 2.0L,
Packit 6c4009
	/* c = (float)0.84506291151 */
Packit 6c4009
  erx = 0.845062911510467529296875L,
Packit 6c4009
/*
Packit 6c4009
 * Coefficients for approximation to  erf on [0,0.84375]
Packit 6c4009
 */
Packit 6c4009
  /* 2/sqrt(pi) - 1 */
Packit 6c4009
  efx = 1.2837916709551257389615890312154517168810E-1L,
Packit 6c4009
Packit 6c4009
  pp[6] = {
Packit 6c4009
    1.122751350964552113068262337278335028553E6L,
Packit 6c4009
    -2.808533301997696164408397079650699163276E6L,
Packit 6c4009
    -3.314325479115357458197119660818768924100E5L,
Packit 6c4009
    -6.848684465326256109712135497895525446398E4L,
Packit 6c4009
    -2.657817695110739185591505062971929859314E3L,
Packit 6c4009
    -1.655310302737837556654146291646499062882E2L,
Packit 6c4009
  },
Packit 6c4009
Packit 6c4009
  qq[6] = {
Packit 6c4009
    8.745588372054466262548908189000448124232E6L,
Packit 6c4009
    3.746038264792471129367533128637019611485E6L,
Packit 6c4009
    7.066358783162407559861156173539693900031E5L,
Packit 6c4009
    7.448928604824620999413120955705448117056E4L,
Packit 6c4009
    4.511583986730994111992253980546131408924E3L,
Packit 6c4009
    1.368902937933296323345610240009071254014E2L,
Packit 6c4009
    /* 1.000000000000000000000000000000000000000E0 */
Packit 6c4009
  },
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * Coefficients for approximation to  erf  in [0.84375,1.25]
Packit 6c4009
 */
Packit 6c4009
/* erf(x+1) = 0.845062911510467529296875 + pa(x)/qa(x)
Packit 6c4009
   -0.15625 <= x <= +.25
Packit 6c4009
   Peak relative error 8.5e-22  */
Packit 6c4009
Packit 6c4009
  pa[8] = {
Packit 6c4009
    -1.076952146179812072156734957705102256059E0L,
Packit 6c4009
     1.884814957770385593365179835059971587220E2L,
Packit 6c4009
    -5.339153975012804282890066622962070115606E1L,
Packit 6c4009
     4.435910679869176625928504532109635632618E1L,
Packit 6c4009
     1.683219516032328828278557309642929135179E1L,
Packit 6c4009
    -2.360236618396952560064259585299045804293E0L,
Packit 6c4009
     1.852230047861891953244413872297940938041E0L,
Packit 6c4009
     9.394994446747752308256773044667843200719E-2L,
Packit 6c4009
  },
Packit 6c4009
Packit 6c4009
  qa[7] =  {
Packit 6c4009
    4.559263722294508998149925774781887811255E2L,
Packit 6c4009
    3.289248982200800575749795055149780689738E2L,
Packit 6c4009
    2.846070965875643009598627918383314457912E2L,
Packit 6c4009
    1.398715859064535039433275722017479994465E2L,
Packit 6c4009
    6.060190733759793706299079050985358190726E1L,
Packit 6c4009
    2.078695677795422351040502569964299664233E1L,
Packit 6c4009
    4.641271134150895940966798357442234498546E0L,
Packit 6c4009
    /* 1.000000000000000000000000000000000000000E0 */
Packit 6c4009
  },
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * Coefficients for approximation to  erfc in [1.25,1/0.35]
Packit 6c4009
 */
Packit 6c4009
/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + ra(x^2)/sa(x^2))
Packit 6c4009
   1/2.85711669921875 < 1/x < 1/1.25
Packit 6c4009
   Peak relative error 3.1e-21  */
Packit 6c4009
Packit 6c4009
    ra[] = {
Packit 6c4009
      1.363566591833846324191000679620738857234E-1L,
Packit 6c4009
      1.018203167219873573808450274314658434507E1L,
Packit 6c4009
      1.862359362334248675526472871224778045594E2L,
Packit 6c4009
      1.411622588180721285284945138667933330348E3L,
Packit 6c4009
      5.088538459741511988784440103218342840478E3L,
Packit 6c4009
      8.928251553922176506858267311750789273656E3L,
Packit 6c4009
      7.264436000148052545243018622742770549982E3L,
Packit 6c4009
      2.387492459664548651671894725748959751119E3L,
Packit 6c4009
      2.220916652813908085449221282808458466556E2L,
Packit 6c4009
    },
Packit 6c4009
Packit 6c4009
    sa[] = {
Packit 6c4009
      -1.382234625202480685182526402169222331847E1L,
Packit 6c4009
      -3.315638835627950255832519203687435946482E2L,
Packit 6c4009
      -2.949124863912936259747237164260785326692E3L,
Packit 6c4009
      -1.246622099070875940506391433635999693661E4L,
Packit 6c4009
      -2.673079795851665428695842853070996219632E4L,
Packit 6c4009
      -2.880269786660559337358397106518918220991E4L,
Packit 6c4009
      -1.450600228493968044773354186390390823713E4L,
Packit 6c4009
      -2.874539731125893533960680525192064277816E3L,
Packit 6c4009
      -1.402241261419067750237395034116942296027E2L,
Packit 6c4009
      /* 1.000000000000000000000000000000000000000E0 */
Packit 6c4009
    },
Packit 6c4009
/*
Packit 6c4009
 * Coefficients for approximation to  erfc in [1/.35,107]
Packit 6c4009
 */
Packit 6c4009
/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rb(x^2)/sb(x^2))
Packit 6c4009
   1/6.6666259765625 < 1/x < 1/2.85711669921875
Packit 6c4009
   Peak relative error 4.2e-22  */
Packit 6c4009
    rb[] = {
Packit 6c4009
      -4.869587348270494309550558460786501252369E-5L,
Packit 6c4009
      -4.030199390527997378549161722412466959403E-3L,
Packit 6c4009
      -9.434425866377037610206443566288917589122E-2L,
Packit 6c4009
      -9.319032754357658601200655161585539404155E-1L,
Packit 6c4009
      -4.273788174307459947350256581445442062291E0L,
Packit 6c4009
      -8.842289940696150508373541814064198259278E0L,
Packit 6c4009
      -7.069215249419887403187988144752613025255E0L,
Packit 6c4009
      -1.401228723639514787920274427443330704764E0L,
Packit 6c4009
    },
Packit 6c4009
Packit 6c4009
    sb[] = {
Packit 6c4009
      4.936254964107175160157544545879293019085E-3L,
Packit 6c4009
      1.583457624037795744377163924895349412015E-1L,
Packit 6c4009
      1.850647991850328356622940552450636420484E0L,
Packit 6c4009
      9.927611557279019463768050710008450625415E0L,
Packit 6c4009
      2.531667257649436709617165336779212114570E1L,
Packit 6c4009
      2.869752886406743386458304052862814690045E1L,
Packit 6c4009
      1.182059497870819562441683560749192539345E1L,
Packit 6c4009
      /* 1.000000000000000000000000000000000000000E0 */
Packit 6c4009
    },
Packit 6c4009
/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rc(x^2)/sc(x^2))
Packit 6c4009
   1/107 <= 1/x <= 1/6.6666259765625
Packit 6c4009
   Peak relative error 1.1e-21  */
Packit 6c4009
    rc[] = {
Packit 6c4009
      -8.299617545269701963973537248996670806850E-5L,
Packit 6c4009
      -6.243845685115818513578933902532056244108E-3L,
Packit 6c4009
      -1.141667210620380223113693474478394397230E-1L,
Packit 6c4009
      -7.521343797212024245375240432734425789409E-1L,
Packit 6c4009
      -1.765321928311155824664963633786967602934E0L,
Packit 6c4009
      -1.029403473103215800456761180695263439188E0L,
Packit 6c4009
    },
Packit 6c4009
Packit 6c4009
    sc[] = {
Packit 6c4009
      8.413244363014929493035952542677768808601E-3L,
Packit 6c4009
      2.065114333816877479753334599639158060979E-1L,
Packit 6c4009
      1.639064941530797583766364412782135680148E0L,
Packit 6c4009
      4.936788463787115555582319302981666347450E0L,
Packit 6c4009
      5.005177727208955487404729933261347679090E0L,
Packit 6c4009
      /* 1.000000000000000000000000000000000000000E0 */
Packit 6c4009
    };
Packit 6c4009
Packit 6c4009
long double
Packit 6c4009
__erfl (long double x)
Packit 6c4009
{
Packit 6c4009
  long double R, S, P, Q, s, y, z, r;
Packit 6c4009
  int32_t ix, i;
Packit 6c4009
  uint32_t se, i0, i1;
Packit 6c4009
Packit 6c4009
  GET_LDOUBLE_WORDS (se, i0, i1, x);
Packit 6c4009
  ix = se & 0x7fff;
Packit 6c4009
Packit 6c4009
  if (ix >= 0x7fff)
Packit 6c4009
    {				/* erf(nan)=nan */
Packit 6c4009
      i = ((se & 0xffff) >> 15) << 1;
Packit 6c4009
      return (long double) (1 - i) + one / x;	/* erf(+-inf)=+-1 */
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  ix = (ix << 16) | (i0 >> 16);
Packit 6c4009
  if (ix < 0x3ffed800) /* |x|<0.84375 */
Packit 6c4009
    {
Packit 6c4009
      if (ix < 0x3fde8000) /* |x|<2**-33 */
Packit 6c4009
	{
Packit 6c4009
	  if (ix < 0x00080000)
Packit 6c4009
	    {
Packit 6c4009
	      /* Avoid spurious underflow.  */
Packit 6c4009
	      long double ret = 0.0625 * (16.0 * x + (16.0 * efx) * x);
Packit 6c4009
	      math_check_force_underflow (ret);
Packit 6c4009
	      return ret;
Packit 6c4009
	    }
Packit 6c4009
	  return x + efx * x;
Packit 6c4009
	}
Packit 6c4009
      z = x * x;
Packit 6c4009
      r = pp[0] + z * (pp[1]
Packit 6c4009
          + z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5]))));
Packit 6c4009
      s = qq[0] + z * (qq[1]
Packit 6c4009
	  + z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z)))));
Packit 6c4009
      y = r / s;
Packit 6c4009
      return x + x * y;
Packit 6c4009
    }
Packit 6c4009
  if (ix < 0x3fffa000) /* 1.25 */
Packit 6c4009
    {				/* 0.84375 <= |x| < 1.25 */
Packit 6c4009
      s = fabsl (x) - one;
Packit 6c4009
      P = pa[0] + s * (pa[1] + s * (pa[2]
Packit 6c4009
        + s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7]))))));
Packit 6c4009
      Q = qa[0] + s * (qa[1] + s * (qa[2]
Packit 6c4009
        + s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s))))));
Packit 6c4009
      if ((se & 0x8000) == 0)
Packit 6c4009
	return erx + P / Q;
Packit 6c4009
      else
Packit 6c4009
	return -erx - P / Q;
Packit 6c4009
    }
Packit 6c4009
  if (ix >= 0x4001d555) /* 6.6666259765625 */
Packit 6c4009
    {				/* inf>|x|>=6.666 */
Packit 6c4009
      if ((se & 0x8000) == 0)
Packit 6c4009
	return one - tiny;
Packit 6c4009
      else
Packit 6c4009
	return tiny - one;
Packit 6c4009
    }
Packit 6c4009
  x = fabsl (x);
Packit 6c4009
  s = one / (x * x);
Packit 6c4009
  if (ix < 0x4000b6db) /* 2.85711669921875 */
Packit 6c4009
    {
Packit 6c4009
      R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] +
Packit 6c4009
          s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8])))))));
Packit 6c4009
      S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] +
Packit 6c4009
          s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s))))))));
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {				/* |x| >= 1/0.35 */
Packit 6c4009
      R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] +
Packit 6c4009
         s * (rb[5] + s * (rb[6] + s * rb[7]))))));
Packit 6c4009
      S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] +
Packit 6c4009
         s * (sb[5] + s * (sb[6] + s))))));
Packit 6c4009
    }
Packit 6c4009
  z = x;
Packit 6c4009
  GET_LDOUBLE_WORDS (i, i0, i1, z);
Packit 6c4009
  i1 = 0;
Packit 6c4009
  SET_LDOUBLE_WORDS (z, i, i0, i1);
Packit 6c4009
  r =
Packit 6c4009
    __ieee754_expl (-z * z - 0.5625) * __ieee754_expl ((z - x) * (z + x) +
Packit 6c4009
						     R / S);
Packit 6c4009
  if ((se & 0x8000) == 0)
Packit 6c4009
    return one - r / x;
Packit 6c4009
  else
Packit 6c4009
    return r / x - one;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
libm_alias_ldouble (__erf, erf)
Packit 6c4009
long double
Packit 6c4009
__erfcl (long double x)
Packit 6c4009
{
Packit 6c4009
  int32_t hx, ix;
Packit 6c4009
  long double R, S, P, Q, s, y, z, r;
Packit 6c4009
  uint32_t se, i0, i1;
Packit 6c4009
Packit 6c4009
  GET_LDOUBLE_WORDS (se, i0, i1, x);
Packit 6c4009
  ix = se & 0x7fff;
Packit 6c4009
  if (ix >= 0x7fff)
Packit 6c4009
    {				/* erfc(nan)=nan */
Packit 6c4009
      /* erfc(+-inf)=0,2 */
Packit 6c4009
      return (long double) (((se & 0xffff) >> 15) << 1) + one / x;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  ix = (ix << 16) | (i0 >> 16);
Packit 6c4009
  if (ix < 0x3ffed800) /* |x|<0.84375 */
Packit 6c4009
    {
Packit 6c4009
      if (ix < 0x3fbe0000) /* |x|<2**-65 */
Packit 6c4009
	return one - x;
Packit 6c4009
      z = x * x;
Packit 6c4009
      r = pp[0] + z * (pp[1]
Packit 6c4009
          + z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5]))));
Packit 6c4009
      s = qq[0] + z * (qq[1]
Packit 6c4009
	  + z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z)))));
Packit 6c4009
      y = r / s;
Packit 6c4009
      if (ix < 0x3ffd8000) /* x<1/4 */
Packit 6c4009
	{
Packit 6c4009
	  return one - (x + x * y);
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	{
Packit 6c4009
	  r = x * y;
Packit 6c4009
	  r += (x - half);
Packit 6c4009
	  return half - r;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
  if (ix < 0x3fffa000) /* 1.25 */
Packit 6c4009
    {				/* 0.84375 <= |x| < 1.25 */
Packit 6c4009
      s = fabsl (x) - one;
Packit 6c4009
      P = pa[0] + s * (pa[1] + s * (pa[2]
Packit 6c4009
        + s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7]))))));
Packit 6c4009
      Q = qa[0] + s * (qa[1] + s * (qa[2]
Packit 6c4009
        + s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s))))));
Packit 6c4009
      if ((se & 0x8000) == 0)
Packit 6c4009
	{
Packit 6c4009
	  z = one - erx;
Packit 6c4009
	  return z - P / Q;
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	{
Packit 6c4009
	  z = erx + P / Q;
Packit 6c4009
	  return one + z;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
  if (ix < 0x4005d600) /* 107 */
Packit 6c4009
    {				/* |x|<107 */
Packit 6c4009
      x = fabsl (x);
Packit 6c4009
      s = one / (x * x);
Packit 6c4009
      if (ix < 0x4000b6db) /* 2.85711669921875 */
Packit 6c4009
	{			/* |x| < 1/.35 ~ 2.857143 */
Packit 6c4009
	  R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] +
Packit 6c4009
              s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8])))))));
Packit 6c4009
	  S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] +
Packit 6c4009
              s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s))))))));
Packit 6c4009
	}
Packit 6c4009
      else if (ix < 0x4001d555) /* 6.6666259765625 */
Packit 6c4009
	{			/* 6.666 > |x| >= 1/.35 ~ 2.857143 */
Packit 6c4009
	  R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] +
Packit 6c4009
	      s * (rb[5] + s * (rb[6] + s * rb[7]))))));
Packit 6c4009
	  S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] +
Packit 6c4009
              s * (sb[5] + s * (sb[6] + s))))));
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	{			/* |x| >= 6.666 */
Packit 6c4009
	  if (se & 0x8000)
Packit 6c4009
	    return two - tiny;	/* x < -6.666 */
Packit 6c4009
Packit 6c4009
	  R = rc[0] + s * (rc[1] + s * (rc[2] + s * (rc[3] +
Packit 6c4009
						    s * (rc[4] + s * rc[5]))));
Packit 6c4009
	  S = sc[0] + s * (sc[1] + s * (sc[2] + s * (sc[3] +
Packit 6c4009
						    s * (sc[4] + s))));
Packit 6c4009
	}
Packit 6c4009
      z = x;
Packit 6c4009
      GET_LDOUBLE_WORDS (hx, i0, i1, z);
Packit 6c4009
      i1 = 0;
Packit 6c4009
      i0 &= 0xffffff00;
Packit 6c4009
      SET_LDOUBLE_WORDS (z, hx, i0, i1);
Packit 6c4009
      r = __ieee754_expl (-z * z - 0.5625) *
Packit 6c4009
	__ieee754_expl ((z - x) * (z + x) + R / S);
Packit 6c4009
      if ((se & 0x8000) == 0)
Packit 6c4009
	{
Packit 6c4009
	  long double ret = r / x;
Packit 6c4009
	  if (ret == 0)
Packit 6c4009
	    __set_errno (ERANGE);
Packit 6c4009
	  return ret;
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	return two - r / x;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      if ((se & 0x8000) == 0)
Packit 6c4009
	{
Packit 6c4009
	  __set_errno (ERANGE);
Packit 6c4009
	  return tiny * tiny;
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	return two - tiny;
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
libm_alias_ldouble (__erfc, erfc)