예제 #1
1
파일: s_sin.c 프로젝트: RobbenBasten/glibc
/* Reduce range of X and compute sin of a + da.  K is the amount by which to
   rotate the quadrants.  This allows us to use the same routine to compute cos
   by simply rotating the quadrants by 1.  */
static inline double
__always_inline
reduce_and_compute (double x, unsigned int k)
{
  double retval = 0, a, da;
  unsigned int n = __branred (x, &a, &da);
  k = (n + k) % 4;
  switch (k)
    {
      case 0:
	if (a * a < 0.01588)
	  retval = bsloww (a, da, x, n);
	else
	  retval = bsloww1 (a, da, x, n);
	break;
      case 2:
	if (a * a < 0.01588)
	  retval = bsloww (-a, -da, x, n);
	else
	  retval = bsloww1 (-a, -da, x, n);
	break;

      case 1:
      case 3:
	retval = bsloww2 (a, da, x, n);
	break;
    }
  return retval;
}
예제 #2
0
파일: s_sincos.c 프로젝트: siddhesh/glibc
/* Consolidated version of reduce_and_compute in s_sin.c that does range
   reduction only once and computes sin and cos together.  */
static inline void
__always_inline
reduce_and_compute_sincos (double x, double *sinx, double *cosx)
{
  double a, da;
  unsigned int n = __branred (x, &a, &da);

  n = n & 3;

  if (n == 1 || n == 2)
    {
      a = -a;
      da = -da;
    }

  if (n & 1)
    {
      double *temp = cosx;
      cosx = sinx;
      sinx = temp;
    }

  if (a * a < 0.01588)
    *sinx = bsloww (a, da, x, n);
  else
    *sinx = bsloww1 (a, da, x, n);
  *cosx = bsloww2 (a, da, x, n);
}
예제 #3
0
파일: s_sin.c 프로젝트: RobbenBasten/glibc
double
SECTION
__cos (double x)
{
  double y, xx, res, t, cor, xn, a, da, db, eps, xn1,
    xn2;
  mynumber u, v;
  int4 k, m, n;

  double retval = 0;

  SET_RESTORE_ROUND_53BIT (FE_TONEAREST);

  u.x = x;
  m = u.i[HIGH_HALF];
  k = 0x7fffffff & m;

  /* |x|<2^-27 => cos(x)=1 */
  if (k < 0x3e400000)
    retval = 1.0;

  else if (k < 0x3feb6000)
    {				/* 2^-27 < |x| < 0.855469 */
      y = fabs (x);
      u.x = big + y;
      y = y - (u.x - big);
      res = do_cos (u, y, &cor);
      retval = (res == res + 1.020 * cor) ? res : cslow2 (x);
    }				/*   else  if (k < 0x3feb6000)    */

  else if (k < 0x400368fd)
    { /* 0.855469  <|x|<2.426265  */ ;
      y = hp0 - fabs (x);
      a = y + hp1;
      da = (y - a) + hp1;
      xx = a * a;
      if (xx < 0.01588)
	{
	  res = TAYLOR_SIN (xx, a, da, cor);
	  cor = (cor > 0) ? 1.02 * cor + 1.0e-31 : 1.02 * cor - 1.0e-31;
	  retval = (res == res + cor) ? res : csloww (a, da, x);
	}
      else
	{
	  if (a > 0)
	    {
	      m = 1;
	    }
	  else
	    {
	      m = 0;
	      a = -a;
	      da = -da;
	    }
	  u.x = big + a;
	  y = a - (u.x - big);
	  res = do_sin (u, y, da, &cor);
	  cor = (cor > 0) ? 1.035 * cor + 1.0e-31 : 1.035 * cor - 1.0e-31;
	  retval = ((res == res + cor) ? ((m) ? res : -res)
		    : csloww1 (a, da, x, m));
	}

    }				/*   else  if (k < 0x400368fd)    */


  else if (k < 0x419921FB)
    {				/* 2.426265<|x|< 105414350 */
      t = (x * hpinv + toint);
      xn = t - toint;
      v.x = t;
      y = (x - xn * mp1) - xn * mp2;
      n = v.i[LOW_HALF] & 3;
      da = xn * mp3;
      a = y - da;
      da = (y - a) - da;
      eps = fabs (x) * 1.2e-30;

      switch (n)
	{
	case 1:
	case 3:
	  xx = a * a;
	  if (n == 1)
	    {
	      a = -a;
	      da = -da;
	    }
	  if (xx < 0.01588)
	    {
	      res = TAYLOR_SIN (xx, a, da, cor);
	      cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps;
	      retval = (res == res + cor) ? res : csloww (a, da, x);
	    }
	  else
	    {
	      if (a > 0)
		{
		  m = 1;
		}
	      else
		{
		  m = 0;
		  a = -a;
		  da = -da;
		}
	      u.x = big + a;
	      y = a - (u.x - big);
	      res = do_sin (u, y, da, &cor);
	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
	      retval = ((res == res + cor) ? ((m) ? res : -res)
			: csloww1 (a, da, x, m));
	    }
	  break;

	case 0:
	case 2:
	  if (a < 0)
	    {
	      a = -a;
	      da = -da;
	    }
	  u.x = big + a;
	  y = a - (u.x - big) + da;
	  res = do_cos (u, y, &cor);
	  cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps;
	  retval = ((res == res + cor) ? ((n) ? -res : res)
		    : csloww2 (a, da, x, n));
	  break;
	}
    }				/*   else  if (k <  0x419921FB )    */

  else if (k < 0x42F00000)
    {
      t = (x * hpinv + toint);
      xn = t - toint;
      v.x = t;
      xn1 = (xn + 8.0e22) - 8.0e22;
      xn2 = xn - xn1;
      y = ((((x - xn1 * mp1) - xn1 * mp2) - xn2 * mp1) - xn2 * mp2);
      n = v.i[LOW_HALF] & 3;
      da = xn1 * pp3;
      t = y - da;
      da = (y - t) - da;
      da = (da - xn2 * pp3) - xn * pp4;
      a = t + da;
      da = (t - a) + da;
      eps = 1.0e-24;

      switch (n)
	{
	case 1:
	case 3:
	  xx = a * a;
	  if (n == 1)
	    {
	      a = -a;
	      da = -da;
	    }
	  if (xx < 0.01588)
	    {
	      res = TAYLOR_SIN (xx, a, da, cor);
	      cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps;
	      retval = (res == res + cor) ? res : bsloww (a, da, x, n);
	    }
	  else
	    {
	      double t;
	      if (a > 0)
		{
		  m = 1;
		  t = a;
		  db = da;
		}
	      else
		{
		  m = 0;
		  t = -a;
		  db = -da;
		}
	      u.x = big + t;
	      y = t - (u.x - big);
	      res = do_sin (u, y, db, &cor);
	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
	      retval = ((res == res + cor) ? ((m) ? res : -res)
			: bsloww1 (a, da, x, n));
	    }
	  break;

	case 0:
	case 2:
	  if (a < 0)
	    {
	      a = -a;
	      da = -da;
	    }
	  u.x = big + a;
	  y = a - (u.x - big) + da;
	  res = do_cos (u, y, &cor);
	  cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps;
	  retval = ((res == res + cor) ? ((n) ? -res : res)
		    : bsloww2 (a, da, x, n));
	  break;
	}
    }				/*   else  if (k <  0x42F00000 )    */

  /* 281474976710656 <|x| <2^1024 */
  else if (k < 0x7ff00000)
    retval = reduce_and_compute (x, 1);

  else
    {
      if (k == 0x7ff00000 && u.i[LOW_HALF] == 0)
	__set_errno (EDOM);
      retval = x / x;		/* |x| > 2^1024 */
    }

  return retval;
}
예제 #4
0
파일: s_sin.c 프로젝트: RobbenBasten/glibc
double
SECTION
__sin (double x)
{
  double xx, res, t, cor, y, s, c, sn, ssn, cs, ccs, xn, a, da, db, eps, xn1,
    xn2;
  mynumber u, v;
  int4 k, m, n;
  double retval = 0;

  SET_RESTORE_ROUND_53BIT (FE_TONEAREST);

  u.x = x;
  m = u.i[HIGH_HALF];
  k = 0x7fffffff & m;		/* no sign           */
  if (k < 0x3e500000)		/* if x->0 =>sin(x)=x */
    {
      math_check_force_underflow (x);
      retval = x;
    }
 /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/
  else if (k < 0x3fd00000)
    {
      xx = x * x;
      /* Taylor series.  */
      t = POLYNOMIAL (xx) * (xx * x);
      res = x + t;
      cor = (x - res) + t;
      retval = (res == res + 1.07 * cor) ? res : slow (x);
    }				/*  else  if (k < 0x3fd00000)    */
/*---------------------------- 0.25<|x|< 0.855469---------------------- */
  else if (k < 0x3feb6000)
    {
      u.x = (m > 0) ? big + x : big - x;
      y = (m > 0) ? x - (u.x - big) : x + (u.x - big);
      xx = y * y;
      s = y + y * xx * (sn3 + xx * sn5);
      c = xx * (cs2 + xx * (cs4 + xx * cs6));
      SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs);
      if (m <= 0)
        {
          sn = -sn;
	  ssn = -ssn;
	}
      cor = (ssn + s * ccs - sn * c) + cs * s;
      res = sn + cor;
      cor = (sn - res) + cor;
      retval = (res == res + 1.096 * cor) ? res : slow1 (x);
    }				/*   else  if (k < 0x3feb6000)    */

/*----------------------- 0.855469  <|x|<2.426265  ----------------------*/
  else if (k < 0x400368fd)
    {

      y = (m > 0) ? hp0 - x : hp0 + x;
      if (y >= 0)
	{
	  u.x = big + y;
	  y = (y - (u.x - big)) + hp1;
	}
      else
	{
	  u.x = big - y;
	  y = (-hp1) - (y + (u.x - big));
	}
      res = do_cos (u, y, &cor);
      retval = (res == res + 1.020 * cor) ? ((m > 0) ? res : -res) : slow2 (x);
    }				/*   else  if (k < 0x400368fd)    */

/*-------------------------- 2.426265<|x|< 105414350 ----------------------*/
  else if (k < 0x419921FB)
    {
      t = (x * hpinv + toint);
      xn = t - toint;
      v.x = t;
      y = (x - xn * mp1) - xn * mp2;
      n = v.i[LOW_HALF] & 3;
      da = xn * mp3;
      a = y - da;
      da = (y - a) - da;
      eps = fabs (x) * 1.2e-30;

      switch (n)
	{			/* quarter of unit circle */
	case 0:
	case 2:
	  xx = a * a;
	  if (n)
	    {
	      a = -a;
	      da = -da;
	    }
	  if (xx < 0.01588)
	    {
	      /* Taylor series.  */
	      res = TAYLOR_SIN (xx, a, da, cor);
	      cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps;
	      retval = (res == res + cor) ? res : sloww (a, da, x);
	    }
	  else
	    {
	      if (a > 0)
		m = 1;
	      else
		{
		  m = 0;
		  a = -a;
		  da = -da;
		}
	      u.x = big + a;
	      y = a - (u.x - big);
	      res = do_sin (u, y, da, &cor);
	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
	      retval = ((res == res + cor) ? ((m) ? res : -res)
			: sloww1 (a, da, x, m));
	    }
	  break;

	case 1:
	case 3:
	  if (a < 0)
	    {
	      a = -a;
	      da = -da;
	    }
	  u.x = big + a;
	  y = a - (u.x - big) + da;
	  res = do_cos (u, y, &cor);
	  cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps;
	  retval = ((res == res + cor) ? ((n & 2) ? -res : res)
		    : sloww2 (a, da, x, n));
	  break;
	}
    }				/*   else  if (k <  0x419921FB )    */

/*---------------------105414350 <|x|< 281474976710656 --------------------*/
  else if (k < 0x42F00000)
    {
      t = (x * hpinv + toint);
      xn = t - toint;
      v.x = t;
      xn1 = (xn + 8.0e22) - 8.0e22;
      xn2 = xn - xn1;
      y = ((((x - xn1 * mp1) - xn1 * mp2) - xn2 * mp1) - xn2 * mp2);
      n = v.i[LOW_HALF] & 3;
      da = xn1 * pp3;
      t = y - da;
      da = (y - t) - da;
      da = (da - xn2 * pp3) - xn * pp4;
      a = t + da;
      da = (t - a) + da;
      eps = 1.0e-24;

      switch (n)
	{
	case 0:
	case 2:
	  xx = a * a;
	  if (n)
	    {
	      a = -a;
	      da = -da;
	    }
	  if (xx < 0.01588)
	    {
	      /* Taylor series.  */
	      res = TAYLOR_SIN (xx, a, da, cor);
	      cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps;
	      retval = (res == res + cor) ? res : bsloww (a, da, x, n);
	    }
	  else
	    {
	      double t;
	      if (a > 0)
		{
		  m = 1;
		  t = a;
		  db = da;
		}
	      else
		{
		  m = 0;
		  t = -a;
		  db = -da;
		}
	      u.x = big + t;
	      y = t - (u.x - big);
	      res = do_sin (u, y, db, &cor);
	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
	      retval = ((res == res + cor) ? ((m) ? res : -res)
			: bsloww1 (a, da, x, n));
	    }
	  break;

	case 1:
	case 3:
	  if (a < 0)
	    {
	      a = -a;
	      da = -da;
	    }
	  u.x = big + a;
	  y = a - (u.x - big) + da;
	  res = do_cos (u, y, &cor);
	  cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps;
	  retval = ((res == res + cor) ? ((n & 2) ? -res : res)
		    : bsloww2 (a, da, x, n));
	  break;
	}
    }				/*   else  if (k <  0x42F00000 )   */

/* -----------------281474976710656 <|x| <2^1024----------------------------*/
  else if (k < 0x7ff00000)
    retval = reduce_and_compute (x, 0);

/*--------------------- |x| > 2^1024 ----------------------------------*/
  else
    {
      if (k == 0x7ff00000 && u.i[LOW_HALF] == 0)
	__set_errno (EDOM);
      retval = x / x;
    }

  return retval;
}
예제 #5
0
double __sin(double x){
	double xx,res,t,cor,y,s,c,sn,ssn,cs,ccs,xn,a,da,db,eps,xn1,xn2;
#if 0
	double w[2];
#endif
	mynumber u,v;
	int4 k,m,n;
#if 0
	int4 nn;
#endif

	u.x = x;
	m = u.i[HIGH_HALF];
	k = 0x7fffffff&m;              /* no sign           */
	if (k < 0x3e500000)            /* if x->0 =>sin(x)=x */
	 return x;
 /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/
	else  if (k < 0x3fd00000){
	  xx = x*x;
	  /*Taylor series */
	  t = ((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*(xx*x);
	  res = x+t;
	  cor = (x-res)+t;
	  return (res == res + 1.07*cor)? res : slow(x);
	}    /*  else  if (k < 0x3fd00000)    */
/*---------------------------- 0.25<|x|< 0.855469---------------------- */
	else if (k < 0x3feb6000)  {
	  u.x=(m>0)?big.x+x:big.x-x;
	  y=(m>0)?x-(u.x-big.x):x+(u.x-big.x);
	  xx=y*y;
	  s = y + y*xx*(sn3 +xx*sn5);
	  c = xx*(cs2 +xx*(cs4 + xx*cs6));
	  k=u.i[LOW_HALF]<<2;
	  sn=(m>0)?sincos.x[k]:-sincos.x[k];
	  ssn=(m>0)?sincos.x[k+1]:-sincos.x[k+1];
	  cs=sincos.x[k+2];
	  ccs=sincos.x[k+3];
	  cor=(ssn+s*ccs-sn*c)+cs*s;
	  res=sn+cor;
	  cor=(sn-res)+cor;
	  return (res==res+1.025*cor)? res : slow1(x);
	}    /*   else  if (k < 0x3feb6000)    */

/*----------------------- 0.855469  <|x|<2.426265  ----------------------*/
	else if (k <  0x400368fd ) {

	  y = (m>0)? hp0.x-x:hp0.x+x;
	  if (y>=0) {
	    u.x = big.x+y;
	    y = (y-(u.x-big.x))+hp1.x;
	  }
	  else {
	    u.x = big.x-y;
	    y = (-hp1.x) - (y+(u.x-big.x));
	  }
	  xx=y*y;
	  s = y + y*xx*(sn3 +xx*sn5);
	  c = xx*(cs2 +xx*(cs4 + xx*cs6));
	  k=u.i[LOW_HALF]<<2;
	  sn=sincos.x[k];
	  ssn=sincos.x[k+1];
	  cs=sincos.x[k+2];
	  ccs=sincos.x[k+3];
	  cor=(ccs-s*ssn-cs*c)-sn*s;
	  res=cs+cor;
	  cor=(cs-res)+cor;
	  return (res==res+1.020*cor)? ((m>0)?res:-res) : slow2(x);
	} /*   else  if (k < 0x400368fd)    */

/*-------------------------- 2.426265<|x|< 105414350 ----------------------*/
	else if (k < 0x419921FB ) {
	  t = (x*hpinv.x + toint.x);
	  xn = t - toint.x;
	  v.x = t;
	  y = (x - xn*mp1.x) - xn*mp2.x;
	  n =v.i[LOW_HALF]&3;
	  da = xn*mp3.x;
	  a=y-da;
	  da = (y-a)-da;
	  eps = ABS(x)*1.2e-30;

	  switch (n) { /* quarter of unit circle */
	  case 0:
	  case 2:
	    xx = a*a;
	    if (n) {a=-a;da=-da;}
	    if (xx < 0.01588) {
                      /*Taylor series */
	      t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
	      res = a+t;
	      cor = (a-res)+t;
	      cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
	      return (res == res + cor)? res : sloww(a,da,x);
	    }
	    else  {
	      if (a>0)
		{m=1;t=a;db=da;}
	      else
		{m=0;t=-a;db=-da;}
	      u.x=big.x+t;
	      y=t-(u.x-big.x);
	      xx=y*y;
	      s = y + (db+y*xx*(sn3 +xx*sn5));
	      c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
	      k=u.i[LOW_HALF]<<2;
	      sn=sincos.x[k];
	      ssn=sincos.x[k+1];
	      cs=sincos.x[k+2];
	      ccs=sincos.x[k+3];
	      cor=(ssn+s*ccs-sn*c)+cs*s;
	      res=sn+cor;
	      cor=(sn-res)+cor;
	      cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
	      return (res==res+cor)? ((m)?res:-res) : sloww1(a,da,x);
	    }
	    break;

	  case 1:
	  case 3:
	    if (a<0)
	      {a=-a;da=-da;}
	    u.x=big.x+a;
	    y=a-(u.x-big.x)+da;
	    xx=y*y;
	    k=u.i[LOW_HALF]<<2;
	    sn=sincos.x[k];
	    ssn=sincos.x[k+1];
	    cs=sincos.x[k+2];
	    ccs=sincos.x[k+3];
	    s = y + y*xx*(sn3 +xx*sn5);
	    c = xx*(cs2 +xx*(cs4 + xx*cs6));
	    cor=(ccs-s*ssn-cs*c)-sn*s;
	    res=cs+cor;
	    cor=(cs-res)+cor;
	    cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
	    return (res==res+cor)? ((n&2)?-res:res) : sloww2(a,da,x,n);

	    break;

	  }

	}    /*   else  if (k <  0x419921FB )    */

/*---------------------105414350 <|x|< 281474976710656 --------------------*/
	else if (k < 0x42F00000 ) {
	  t = (x*hpinv.x + toint.x);
	  xn = t - toint.x;
	  v.x = t;
	  xn1 = (xn+8.0e22)-8.0e22;
	  xn2 = xn - xn1;
	  y = ((((x - xn1*mp1.x) - xn1*mp2.x)-xn2*mp1.x)-xn2*mp2.x);
	  n =v.i[LOW_HALF]&3;
	  da = xn1*pp3.x;
	  t=y-da;
	  da = (y-t)-da;
	  da = (da - xn2*pp3.x) -xn*pp4.x;
	  a = t+da;
	  da = (t-a)+da;
	  eps = 1.0e-24;

	  switch (n) {
	  case 0:
	  case 2:
	    xx = a*a;
	    if (n) {a=-a;da=-da;}
	    if (xx < 0.01588) {
              /* Taylor series */
	      t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
	      res = a+t;
	      cor = (a-res)+t;
	      cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
	      return (res == res + cor)? res : bsloww(a,da,x,n);
	    }
	    else  {
	      if (a>0) {m=1;t=a;db=da;}
	      else {m=0;t=-a;db=-da;}
	      u.x=big.x+t;
	      y=t-(u.x-big.x);
	      xx=y*y;
	      s = y + (db+y*xx*(sn3 +xx*sn5));
	      c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
	      k=u.i[LOW_HALF]<<2;
	      sn=sincos.x[k];
	      ssn=sincos.x[k+1];
	      cs=sincos.x[k+2];
	      ccs=sincos.x[k+3];
	      cor=(ssn+s*ccs-sn*c)+cs*s;
	      res=sn+cor;
	      cor=(sn-res)+cor;
	      cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
	      return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
		   }
	    break;

	  case 1:
	  case 3:
	    if (a<0)
	      {a=-a;da=-da;}
	    u.x=big.x+a;
	    y=a-(u.x-big.x)+da;
	    xx=y*y;
	    k=u.i[LOW_HALF]<<2;
	    sn=sincos.x[k];
	    ssn=sincos.x[k+1];
	    cs=sincos.x[k+2];
	    ccs=sincos.x[k+3];
	    s = y + y*xx*(sn3 +xx*sn5);
	    c = xx*(cs2 +xx*(cs4 + xx*cs6));
	    cor=(ccs-s*ssn-cs*c)-sn*s;
	    res=cs+cor;
	    cor=(cs-res)+cor;
	    cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
	    return (res==res+cor)? ((n&2)?-res:res) : bsloww2(a,da,x,n);

	    break;

	  }

	}    /*   else  if (k <  0x42F00000 )   */

/* -----------------281474976710656 <|x| <2^1024----------------------------*/
	else if (k < 0x7ff00000) {

	  n = __branred(x,&a,&da);
	  switch (n) {
	  case 0:
	    if (a*a < 0.01588) return bsloww(a,da,x,n);
	    else return bsloww1(a,da,x,n);
	    break;
	  case 2:
	    if (a*a < 0.01588) return bsloww(-a,-da,x,n);
	    else return bsloww1(-a,-da,x,n);
	    break;

	  case 1:
	  case 3:
	    return  bsloww2(a,da,x,n);
	    break;
	  }

	}    /*   else  if (k <  0x7ff00000 )    */

/*--------------------- |x| > 2^1024 ----------------------------------*/
	else return x / x;
	return 0;         /* unreachable */
}
예제 #6
0
double __cos(double x)
{
  double y,xx,res,t,cor,s,c,sn,ssn,cs,ccs,xn,a,da,db,eps,xn1,xn2;
  mynumber u,v;
  int4 k,m,n;

  u.x = x;
  m = u.i[HIGH_HALF];
  k = 0x7fffffff&m;

  if (k < 0x3e400000 ) return 1.0; /* |x|<2^-27 => cos(x)=1 */

  else if (k < 0x3feb6000 ) {/* 2^-27 < |x| < 0.855469 */
    y=ABS(x);
    u.x = big.x+y;
    y = y-(u.x-big.x);
    xx=y*y;
    s = y + y*xx*(sn3 +xx*sn5);
    c = xx*(cs2 +xx*(cs4 + xx*cs6));
    k=u.i[LOW_HALF]<<2;
    sn=sincos.x[k];
    ssn=sincos.x[k+1];
    cs=sincos.x[k+2];
    ccs=sincos.x[k+3];
    cor=(ccs-s*ssn-cs*c)-sn*s;
    res=cs+cor;
    cor=(cs-res)+cor;
    return (res==res+1.020*cor)? res : cslow2(x);

}    /*   else  if (k < 0x3feb6000)    */

  else if (k <  0x400368fd ) {/* 0.855469  <|x|<2.426265  */;
    y=hp0.x-ABS(x);
    a=y+hp1.x;
    da=(y-a)+hp1.x;
    xx=a*a;
    if (xx < 0.01588) {
      t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
      res = a+t;
      cor = (a-res)+t;
      cor = (cor>0)? 1.02*cor+1.0e-31 : 1.02*cor -1.0e-31;
      return (res == res + cor)? res : csloww(a,da,x);
    }
    else  {
      if (a>0) {m=1;t=a;db=da;}
      else {m=0;t=-a;db=-da;}
      u.x=big.x+t;
      y=t-(u.x-big.x);
      xx=y*y;
      s = y + (db+y*xx*(sn3 +xx*sn5));
      c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
      k=u.i[LOW_HALF]<<2;
      sn=sincos.x[k];
      ssn=sincos.x[k+1];
      cs=sincos.x[k+2];
      ccs=sincos.x[k+3];
      cor=(ssn+s*ccs-sn*c)+cs*s;
      res=sn+cor;
      cor=(sn-res)+cor;
      cor = (cor>0)? 1.035*cor+1.0e-31 : 1.035*cor-1.0e-31;
      return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
}

}    /*   else  if (k < 0x400368fd)    */


  else if (k < 0x419921FB ) {/* 2.426265<|x|< 105414350 */
    t = (x*hpinv.x + toint.x);
    xn = t - toint.x;
    v.x = t;
    y = (x - xn*mp1.x) - xn*mp2.x;
    n =v.i[LOW_HALF]&3;
    da = xn*mp3.x;
    a=y-da;
    da = (y-a)-da;
    eps = ABS(x)*1.2e-30;

    switch (n) {
    case 1:
    case 3:
      xx = a*a;
      if (n == 1) {a=-a;da=-da;}
      if (xx < 0.01588) {
	t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
	res = a+t;
	cor = (a-res)+t;
	cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
	return (res == res + cor)? res : csloww(a,da,x);
      }
      else  {
	if (a>0) {m=1;t=a;db=da;}
	else {m=0;t=-a;db=-da;}
	u.x=big.x+t;
	y=t-(u.x-big.x);
	xx=y*y;
	s = y + (db+y*xx*(sn3 +xx*sn5));
	c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
	k=u.i[LOW_HALF]<<2;
	sn=sincos.x[k];
	ssn=sincos.x[k+1];
	cs=sincos.x[k+2];
	ccs=sincos.x[k+3];
	cor=(ssn+s*ccs-sn*c)+cs*s;
	res=sn+cor;
	cor=(sn-res)+cor;
	cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
	return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
      }
      break;

  case 0:
    case 2:
      if (a<0) {a=-a;da=-da;}
      u.x=big.x+a;
      y=a-(u.x-big.x)+da;
      xx=y*y;
      k=u.i[LOW_HALF]<<2;
      sn=sincos.x[k];
      ssn=sincos.x[k+1];
      cs=sincos.x[k+2];
      ccs=sincos.x[k+3];
      s = y + y*xx*(sn3 +xx*sn5);
      c = xx*(cs2 +xx*(cs4 + xx*cs6));
      cor=(ccs-s*ssn-cs*c)-sn*s;
      res=cs+cor;
      cor=(cs-res)+cor;
      cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
      return (res==res+cor)? ((n)?-res:res) : csloww2(a,da,x,n);

           break;

    }

  }    /*   else  if (k <  0x419921FB )    */


  else if (k < 0x42F00000 ) {
    t = (x*hpinv.x + toint.x);
    xn = t - toint.x;
    v.x = t;
    xn1 = (xn+8.0e22)-8.0e22;
    xn2 = xn - xn1;
    y = ((((x - xn1*mp1.x) - xn1*mp2.x)-xn2*mp1.x)-xn2*mp2.x);
    n =v.i[LOW_HALF]&3;
    da = xn1*pp3.x;
    t=y-da;
    da = (y-t)-da;
    da = (da - xn2*pp3.x) -xn*pp4.x;
    a = t+da;
    da = (t-a)+da;
    eps = 1.0e-24;

    switch (n) {
    case 1:
    case 3:
      xx = a*a;
      if (n==1) {a=-a;da=-da;}
      if (xx < 0.01588) {
	t = (((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*a - 0.5*da)*xx+da;
	res = a+t;
	cor = (a-res)+t;
	cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
	return (res == res + cor)? res : bsloww(a,da,x,n);
      }
      else  {
	if (a>0) {m=1;t=a;db=da;}
	else {m=0;t=-a;db=-da;}
	u.x=big.x+t;
	y=t-(u.x-big.x);
	xx=y*y;
	s = y + (db+y*xx*(sn3 +xx*sn5));
	c = y*db+xx*(cs2 +xx*(cs4 + xx*cs6));
	k=u.i[LOW_HALF]<<2;
	sn=sincos.x[k];
	ssn=sincos.x[k+1];
	cs=sincos.x[k+2];
	ccs=sincos.x[k+3];
	cor=(ssn+s*ccs-sn*c)+cs*s;
	res=sn+cor;
	cor=(sn-res)+cor;
	cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
	return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
      }
      break;

    case 0:
    case 2:
      if (a<0) {a=-a;da=-da;}
      u.x=big.x+a;
      y=a-(u.x-big.x)+da;
      xx=y*y;
      k=u.i[LOW_HALF]<<2;
      sn=sincos.x[k];
      ssn=sincos.x[k+1];
      cs=sincos.x[k+2];
      ccs=sincos.x[k+3];
      s = y + y*xx*(sn3 +xx*sn5);
      c = xx*(cs2 +xx*(cs4 + xx*cs6));
      cor=(ccs-s*ssn-cs*c)-sn*s;
      res=cs+cor;
      cor=(cs-res)+cor;
      cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
      return (res==res+cor)? ((n)?-res:res) : bsloww2(a,da,x,n);
      break;

    }

  }    /*   else  if (k <  0x42F00000 )    */

  else if (k < 0x7ff00000) {/* 281474976710656 <|x| <2^1024 */

    n = __branred(x,&a,&da);
    switch (n) {
    case 1:
      if (a*a < 0.01588) return bsloww(-a,-da,x,n);
      else return bsloww1(-a,-da,x,n);
      break;
		case 3:
		  if (a*a < 0.01588) return bsloww(a,da,x,n);
		  else return bsloww1(a,da,x,n);
		  break;

    case 0:
    case 2:
      return  bsloww2(a,da,x,n);
      break;
    }

  }    /*   else  if (k <  0x7ff00000 )    */




  else return x / x; /* |x| > 2^1024 */
  return 0;

}