Esempio n. 1
0
void
SECTION
__mpsqrt (mp_no *x, mp_no *y, int p)
{
  int i, m, ey;
  double dx, dy;
  static const mp_no mphalf = {0, {1.0, HALFRAD}};
  static const mp_no mp3halfs = {1, {1.0, 1.0, HALFRAD}};
  mp_no mpxn, mpz, mpu, mpt1, mpt2;

  ey = EX / 2;
  __cpy (x, &mpxn, p);
  mpxn.e -= (ey + ey);
  __mp_dbl (&mpxn, &dx, p);
  dy = fastiroot (dx);
  __dbl_mp (dy, &mpu, p);
  __mul (&mpxn, &mphalf, &mpz, p);

  m = __mpsqrt_mp[p];
  for (i = 0; i < m; i++)
    {
      __sqr (&mpu, &mpt1, p);
      __mul (&mpt1, &mpz, &mpt2, p);
      __sub (&mp3halfs, &mpt2, &mpt1, p);
      __mul (&mpu, &mpt1, &mpt2, p);
      __cpy (&mpt2, &mpu, p);
    }
  __mul (&mpxn, &mpu, y, p);
  EY += ey;
}
Esempio n. 2
0
static void
SECTION
ss32(mp_no *x, mp_no *y, int p) {
  int i;
  double a;
  mp_no mpt1,x2,gor,sum ,mpk={1,{1.0}};
  for (i=1;i<=p;i++) mpk.d[i]=0;

  __sqr(x,&x2,p);
  __cpy(&oofac27,&gor,p);
  __cpy(&gor,&sum,p);
  for (a=27.0;a>1.0;a-=2.0) {
    mpk.d[1]=a*(a-1.0);
    __mul(&gor,&mpk,&mpt1,p);
    __cpy(&mpt1,&gor,p);
    __mul(&x2,&sum,&mpt1,p);
    __sub(&gor,&mpt1,&sum,p);
  }
  __mul(x,&sum,y,p);
}
Esempio n. 3
0
/* Multi-Precision exponential function subroutine (for p >= 4,
   2**(-55) <= abs(x) <= 1024).  */
void
SECTION
__mpexp (mp_no *x, mp_no *y, int p)
{
  int i, j, k, m, m1, m2, n;
  mantissa_t b;
  static const int np[33] =
    {
      0, 0, 0, 0, 3, 3, 4, 4, 5, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6,
      6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8
    };

  static const int m1p[33] =
    {
      0, 0, 0, 0,
      17, 23, 23, 28,
      27, 38, 42, 39,
      43, 47, 43, 47,
      50, 54, 57, 60,
      64, 67, 71, 74,
      68, 71, 74, 77,
      70, 73, 76, 78,
      81
    };
  static const int m1np[7][18] =
    {
      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      {0, 0, 0, 0, 36, 48, 60, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      {0, 0, 0, 0, 24, 32, 40, 48, 56, 64, 72, 0, 0, 0, 0, 0, 0, 0},
      {0, 0, 0, 0, 17, 23, 29, 35, 41, 47, 53, 59, 65, 0, 0, 0, 0, 0},
      {0, 0, 0, 0, 0, 0, 23, 28, 33, 38, 42, 47, 52, 57, 62, 66, 0, 0},
      {0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 39, 43, 47, 51, 55, 59, 63},
      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 47, 50, 54}
    };
  mp_no mps, mpk, mpt1, mpt2;

  /* Choose m,n and compute a=2**(-m).  */
  n = np[p];
  m1 = m1p[p];
  b = X[1];
  m2 = 24 * EX;
  for (; b < HALFRAD; m2--)
    b *= 2;
  if (b == HALFRAD)
    {
      for (i = 2; i <= p; i++)
	{
	  if (X[i] != 0)
	    break;
	}
      if (i == p + 1)
	m2--;
    }

  m = m1 + m2;
  if (__glibc_unlikely (m <= 0))
    {
      /* The m1np array which is used to determine if we can reduce the
	 polynomial expansion iterations, has only 18 elements.  Besides,
	 numbers smaller than those required by p >= 18 should not come here
	 at all since the fast phase of exp returns 1.0 for anything less
	 than 2^-55.  */
      assert (p < 18);
      m = 0;
      for (i = n - 1; i > 0; i--, n--)
	if (m1np[i][p] + m2 > 0)
	  break;
    }

  /* Compute s=x*2**(-m). Put result in mps.  This is the range-reduced input
     that we will use to compute e^s.  For the final result, simply raise it
     to 2^m.  */
  __pow_mp (-m, &mpt1, p);
  __mul (x, &mpt1, &mps, p);

  /* Compute the Taylor series for e^s:

         1 + x/1! + x^2/2! + x^3/3! ...

     for N iterations.  We compute this as:

         e^x = 1 + (x * n!/1! + x^2 * n!/2! + x^3 * n!/3!) / n!
             = 1 + (x * (n!/1! + x * (n!/2! + x * (n!/3! + x ...)))) / n!

     k! is computed on the fly as KF and at the end of the polynomial loop, KF
     is n!, which can be used directly.  */
  __cpy (&mps, &mpt2, p);

  double kf = 1.0;

  /* Evaluate the rest.  The result will be in mpt2.  */
  for (k = n - 1; k > 0; k--)
    {
      /* n! / k! = n * (n - 1) ... * (n - k + 1) */
      kf *= k + 1;

      __dbl_mp (kf, &mpk, p);
      __add (&mpt2, &mpk, &mpt1, p);
      __mul (&mps, &mpt1, &mpt2, p);
    }
  __dbl_mp (kf, &mpk, p);
  __dvd (&mpt2, &mpk, &mpt1, p);
  __add (&__mpone, &mpt1, &mpt2, p);

  /* Raise polynomial value to the power of 2**m. Put result in y.  */
  for (k = 0, j = 0; k < m;)
    {
      __sqr (&mpt2, &mpt1, p);
      k++;
      if (k == m)
	{
	  j = 1;
	  break;
	}
      __sqr (&mpt1, &mpt2, p);
      k++;
    }
  if (j)
    __cpy (&mpt1, y, p);
  else
    __cpy (&mpt2, y, p);
  return;
}
Esempio n. 4
0
File: mpatan.c Progetto: walac/glibc
void
SECTION
__mpatan (mp_no *x, mp_no *y, int p)
{
  int i, m, n;
  double dx;
  mp_no mptwoim1 =
  {
    0,
    {
      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
    }
  };

  mp_no mps, mpsm, mpt, mpt1, mpt2, mpt3;

  /* Choose m and initiate mptwoim1.  */
  if (EX > 0)
    m = 7;
  else if (EX < 0)
    m = 0;
  else
    {
      __mp_dbl (x, &dx, p);
      dx = ABS (dx);
      for (m = 6; m > 0; m--)
	{
	  if (dx > __atan_xm[m].d)
	    break;
	}
    }
  mptwoim1.e = 1;
  mptwoim1.d[0] = 1;

  /* Reduce x m times.  */
  __sqr (x, &mpsm, p);
  if (m == 0)
    __cpy (x, &mps, p);
  else
    {
      for (i = 0; i < m; i++)
	{
	  __add (&mpone, &mpsm, &mpt1, p);
	  __mpsqrt (&mpt1, &mpt2, p);
	  __add (&mpt2, &mpt2, &mpt1, p);
	  __add (&mptwo, &mpsm, &mpt2, p);
	  __add (&mpt1, &mpt2, &mpt3, p);
	  __dvd (&mpsm, &mpt3, &mpt1, p);
	  __cpy (&mpt1, &mpsm, p);
	}
      __mpsqrt (&mpsm, &mps, p);
      mps.d[0] = X[0];
    }

  /* Evaluate a truncated power series for Atan(s).  */
  n = __atan_np[p];
  mptwoim1.d[1] = __atan_twonm1[p].d;
  __dvd (&mpsm, &mptwoim1, &mpt, p);
  for (i = n - 1; i > 1; i--)
    {
      mptwoim1.d[1] -= 2;
      __dvd (&mpsm, &mptwoim1, &mpt1, p);
      __mul (&mpsm, &mpt, &mpt2, p);
      __sub (&mpt1, &mpt2, &mpt, p);
    }
  __mul (&mps, &mpt, &mpt1, p);
  __sub (&mps, &mpt1, &mpt, p);

  /* Compute Atan(x).  */
  mptwoim1.d[1] = 1 << m;
  __mul (&mptwoim1, &mpt, y, p);
}