Beispiel #1
0
/* Receive double x and two double results of cos(x) and return result which is
   more accurate, computing cos(x) with multi precision routine c32.  */
double
SECTION
__cos32 (double x, double res, double res1)
{
  int p;
  mp_no a, b, c;
  p = 32;
  __dbl_mp (res, &a, p);
  __dbl_mp (0.5 * (res1 - res), &b, p);
  __add (&a, &b, &c, p);
  if (x > 2.4)
    {
      __sub (&pi, &c, &a, p);
      __c32 (&a, &b, &c, p);
      b.d[0] = -b.d[0];
    }
  else if (x > 0.8)
    {
      __sub (&hp, &c, &a, p);
      __c32 (&a, &c, &b, p);
    }
  else
    __c32 (&c, &b, &a, p);	/* b=cos(0.5*(res+res1))  */
  __dbl_mp (x, &c, p);		/* c = x                  */
  __sub (&b, &c, &a, p);
  /* if a > 0 return max (res, res1), otherwise return min (res, res1).  */
  if ((a.d[0] > 0 && res <= res1) || (a.d[0] <= 0 && res >= res1))
    res = res1;
  LIBC_PROBE (slowacos, 2, &res, &x);
  return res;
}
Beispiel #2
0
double
SECTION
__cos32(double x, double res, double res1) {
  int p;
  mp_no a,b,c;
  p=32;
  __dbl_mp(res,&a,p);
  __dbl_mp(0.5*(res1-res),&b,p);
  __add(&a,&b,&c,p);
  if (x>2.4)
  { __sub(&pi,&c,&a,p);
    __c32(&a,&b,&c,p);
    b.d[0]=-b.d[0];
  }
  else if (x>0.8)
       { __sub(&hp,&c,&a,p);
	 __c32(&a,&c,&b,p);
       }
  else __c32(&c,&b,&a,p);     /* b=cos(0.5*(res+res1))  */
  __dbl_mp(x,&c,p);    /* c = x                  */
  __sub(&b,&c,&a,p);
	     /* if a>0 return max(res,res1), otherwise return min(res,res1) */
  if (a.d[0]>0)  return (res>res1)?res:res1;
  else  return (res<res1)?res:res1;
}
Beispiel #3
0
/* Compute cos() of double-length number (X + DX) as Multi Precision number and
   return result as double.  If REDUCE_RANGE is true, X is assumed to be the
   original input and DX is ignored.  */
double
SECTION
__mpcos (double x, double dx, bool reduce_range)
{
  double y;
  mp_no a, b, c, s;
  int n;
  int p = 32;

  if (reduce_range)
    {
      n = __mpranred (x, &a, p);	/* n is 0, 1, 2 or 3.  */
      __c32 (&a, &c, &s, p);
    }
  else
    {
      n = -1;
      __dbl_mp (x, &b, p);
      __dbl_mp (dx, &c, p);
      __add (&b, &c, &a, p);
      if (x > 0.8)
        {
          __sub (&hp, &a, &b, p);
          __c32 (&b, &s, &c, p);
        }
      else
        __c32 (&a, &c, &s, p);	/* a = cos(x+dx)     */
    }

  /* Convert result based on which quarter of unit circle y is in.  */
  switch (n)
    {
    case 1:
      __mp_dbl (&s, &y, p);
      y = -y;
      break;

    case 3:
      __mp_dbl (&s, &y, p);
      break;

    case 2:
      __mp_dbl (&c, &y, p);
      y = -y;
      break;

    /* Quadrant not set, so the result must be cos (X + DX), which is also
       stored in C.  */
    case 0:
    default:
      __mp_dbl (&c, &y, p);
    }
  LIBC_PROBE (slowcos, 3, &x, &dx, &y);
  return y;
}
Beispiel #4
0
double __mpsin(double x, double dx) {
  int p;
  double y;
  mp_no a,b,c;
  p=32;
  __dbl_mp(x,&a,p);
  __dbl_mp(dx,&b,p);
  __add(&a,&b,&c,p);
  if (x>0.8) { __sub(&hp,&c,&a,p); __c32(&a,&b,&c,p); }
  else __c32(&c,&a,&b,p);     /* b = sin(x+dx)     */
  __mp_dbl(&b,&y,p);
  return y;
}
Beispiel #5
0
double
SECTION
__mpsin1(double x)
{
  int p;
  int n;
  mp_no u,s,c;
  double y;
  p=32;
  n=__mpranred(x,&u,p);               /* n is 0, 1, 2 or 3 */
  __c32(&u,&c,&s,p);
  switch (n) {                      /* in which quarter of unit circle y is*/
  case 0:
    __mp_dbl(&s,&y,p);
    return y;
    break;

  case 2:
    __mp_dbl(&s,&y,p);
    return -y;
    break;

  case 1:
    __mp_dbl(&c,&y,p);
    return y;
    break;

  case 3:
    __mp_dbl(&c,&y,p);
    return -y;
    break;

  }
  return 0;                     /* unreachable, to make the compiler happy */
}
Beispiel #6
0
void
SECTION
__mptan (double x, mp_no *mpy, int p)
{
  int n;
  mp_no mpw, mpc, mps;

  /* Negative or positive result.  */
  n = __mpranred (x, &mpw, p) & 0x00000001;
  /* Computing sin(x) and cos(x).  */
  __c32 (&mpw, &mpc, &mps, p);
  /* Second or fourth quarter of unit circle.  */
  if (n)
    {
      __dvd (&mpc, &mps, mpy, p);
      mpy->d[0] *= -1;
    }
  /* tan is negative in this area.  */
  else
    __dvd (&mps, &mpc, mpy, p);
}