예제 #1
0
void __mplog(mp_no *x, mp_no *y, int p) {
#include "mplog.h"
  int i,m;
#if 0
  int j,k,m1,m2,n;
  double a,b;
#endif
  static const int mp[33] = {0,0,0,0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
                             4,4,4,4,4,4,4,4,4,4,4,4,4,4};
  mp_no mpone = {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 mpt1,mpt2;

  /* Choose m and initiate mpone */
  m = mp[p];  mpone.e = 1;  mpone.d[0]=mpone.d[1]=ONE;

  /* Perform m newton iterations to solve for y: exp(y)-x=0.     */
  /* The iterations formula is:  y(n+1)=y(n)+(x*exp(-y(n))-1).   */
  __cpy(y,&mpt1,p);
  for (i=0; i<m; i++) {
    mpt1.d[0]=-mpt1.d[0];
    __mpexp(&mpt1,&mpt2,p);
    __mul(x,&mpt2,&mpt1,p);
    __sub(&mpt1,&mpone,&mpt2,p);
    __add(y,&mpt2,&mpt1,p);
    __cpy(&mpt1,y,p);
  }
  return;
}
예제 #2
0
파일: mpsqrt.c 프로젝트: riscv/riscv-glibc
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;
}
예제 #3
0
static void
SECTION
cc32(mp_no *x, mp_no *y, int p) {
  int i;
  double a;
#if 0
  double b;
  static const mp_no mpone = {1,{1.0,1.0}};
#endif
  mp_no mpt1,x2,gor,sum ,mpk={1,{1.0}};
#if 0
  mp_no mpt2;
#endif
  for (i=1;i<=p;i++) mpk.d[i]=0;

  __mul(x,x,&x2,p);
  mpk.d[1]=27.0;
  __mul(&oofac27,&mpk,&gor,p);
  __cpy(&gor,&sum,p);
  for (a=26.0;a>2.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(&x2,&sum,y,p);
}
void __inv(const mp_no *x, mp_no *y, int p) {
  int i;
#if 0
  int l;
#endif
  double t;
  mp_no z,w;
  static const int np1[] = {0,0,0,0,1,2,2,2,2,3,3,3,3,3,3,3,3,3,
                            4,4,4,4,4,4,4,4,4,4,4,4,4,4,4};
  const mp_no mptwo = {1,{1.0,2.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}};

  __cpy(x,&z,p);  z.e=0;  __mp_dbl(&z,&t,p);
  t=ONE/t;   __dbl_mp(t,y,p);    EY -= EX;

  for (i=0; i<np1[p]; i++) {
    __cpy(y,&w,p);
    __mul(x,&w,y,p);
    __sub(&mptwo,y,&z,p);
    __mul(&w,&z,y,p);
  }
  return;
}
예제 #5
0
/* Invert *X and store in *Y.  Relative error bound:
   - For P = 2: 1.001 * R ^ (1 - P)
   - For P = 3: 1.063 * R ^ (1 - P)
   - For P > 3: 2.001 * R ^ (1 - P)

   *X = 0 is not permissible.  */
static void
SECTION
__inv (const mp_no *x, mp_no *y, int p)
{
  long i;
  double t;
  mp_no z, w;
  static const int np1[] =
    { 0, 0, 0, 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
  };

  __cpy (x, &z, p);
  z.e = 0;
  __mp_dbl (&z, &t, p);
  t = 1 / t;
  __dbl_mp (t, y, p);
  EY -= EX;

  for (i = 0; i < np1[p]; i++)
    {
      __cpy (y, &w, p);
      __mul (x, &w, y, p);
      __sub (&__mptwo, y, &z, p);
      __mul (&w, &z, y, p);
    }
}
static void add_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) {

  int i,j,k;

  EZ = EX;

  i=p;    j=p+ EY - EX;    k=p+1;

  if (j<1)
     {__cpy(x,z,p);  return; }
  else   Z[k] = ZERO;

  for (; j>0; i--,j--) {
    Z[k] += X[i] + Y[j];
    if (Z[k] >= RADIX) {
      Z[k]  -= RADIX;
      Z[--k] = ONE; }
    else
      Z[--k] = ZERO;
  }

  for (; i>0; i--) {
    Z[k] += X[i];
    if (Z[k] >= RADIX) {
      Z[k]  -= RADIX;
      Z[--k] = ONE; }
    else
      Z[--k] = ZERO;
  }

  if (Z[1] == ZERO) {
    for (i=1; i<=p; i++)    Z[i] = Z[i+1]; }
  else   EZ += ONE;
}
예제 #7
0
/* Subtract *Y from *X and return the result in *Z.  X and Y may overlap but
   not X and Z or Y and Z.  One guard digit is used.  The error is less than
   one ULP.  */
void
SECTION
__sub (const mp_no *x, const mp_no *y, mp_no *z, int p)
{
  int n;

  if (X[0] == 0)
    {
      __cpy (y, z, p);
      Z[0] = -Z[0];
      return;
    }
  else if (Y[0] == 0)
    {
      __cpy (x, z, p);
      return;
    }

  if (X[0] != Y[0])
    {
      if (__acr (x, y, p) > 0)
	{
	  add_magnitudes (x, y, z, p);
	  Z[0] = X[0];
	}
      else
	{
	  add_magnitudes (y, x, z, p);
	  Z[0] = -Y[0];
	}
    }
  else
    {
      if ((n = __acr (x, y, p)) == 1)
	{
	  sub_magnitudes (x, y, z, p);
	  Z[0] = X[0];
	}
      else if (n == -1)
	{
	  sub_magnitudes (y, x, z, p);
	  Z[0] = -Y[0];
	}
      else
	Z[0] = 0;
    }
}
예제 #8
0
Clustering::Cluster &Clustering::Cluster::operator=(const Clustering::Cluster &cluster) {
    if(*this == cluster) {
        return *this;
    }
    this->~Cluster();
    __cpy(cluster.__points, cluster.__size);
    return *this;
}
예제 #9
0
 Cluster& Cluster::operator=(const Cluster & other){
     if(this != &other){
         //delete & copy
         __size = other.__size;
         __del();
         __cpy(other.__points);
     }
     return *this;
 }
void __add(const mp_no *x, const mp_no *y, mp_no *z, int p) {

  int n;

  if      (X[0] == ZERO)     {__cpy(y,z,p);  return; }
  else if (Y[0] == ZERO)     {__cpy(x,z,p);  return; }

  if (X[0] == Y[0])   {
    if (__acr(x,y,p) > 0)      {add_magnitudes(x,y,z,p);  Z[0] = X[0]; }
    else                     {add_magnitudes(y,x,z,p);  Z[0] = Y[0]; }
  }
  else                       {
    if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p);  Z[0] = X[0]; }
    else if (n == -1)        {sub_magnitudes(y,x,z,p);  Z[0] = Y[0]; }
    else                      Z[0] = ZERO;
  }
  return;
}
예제 #11
0
void __c32(mp_no *x, mp_no *y, mp_no *z, int p) {
  static const mp_no mpt={1,{1.0,2.0}}, one={1,{1.0,1.0}};
  mp_no u,t,t1,t2,c,s;
  int i;
  __cpy(x,&u,p);
  u.e=u.e-1;
  cc32(&u,&c,p);
  ss32(&u,&s,p);
  for (i=0;i<24;i++) {
    __mul(&c,&s,&t,p);
    __sub(&s,&t,&t1,p);
    __add(&t1,&t1,&s,p);
    __sub(&mpt,&c,&t1,p);
    __mul(&t1,&c,&t2,p);
    __add(&t2,&t2,&c,p);
  }
  __sub(&one,&c,y,p);
  __cpy(&s,z,p);
}
예제 #12
0
파일: sincos32.c 프로젝트: gf-chen/glibc
void
SECTION
__c32(mp_no *x, mp_no *y, mp_no *z, int p) {
  mp_no u,t,t1,t2,c,s;
  int i;
  __cpy(x,&u,p);
  u.e=u.e-1;
  cc32(&u,&c,p);
  ss32(&u,&s,p);
  for (i=0;i<24;i++) {
    __mul(&c,&s,&t,p);
    __sub(&s,&t,&t1,p);
    __add(&t1,&t1,&s,p);
    __sub(&mptwo,&c,&t1,p);
    __mul(&t1,&c,&t2,p);
    __add(&t2,&t2,&c,p);
  }
  __sub(&mpone,&c,y,p);
  __cpy(&s,z,p);
}
예제 #13
0
 Cluster::Cluster(const Cluster &C1) : centroid(C1.__dimensionality,C1){
     __id = C1.__id;
     __dimensionality = C1.__dimensionality;
     __size = C1.getSize();
     if(C1.__points != nullptr){
         __cpy(C1.__points);
     }
     else{
         __points = nullptr;
     }
 }
예제 #14
0
파일: sincos32.c 프로젝트: gf-chen/glibc
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);
}
예제 #15
0
    Cluster::Cluster(const Cluster &other) {

        if (other.__points == nullptr)
        {
            __size = other.__size;
            __points = nullptr;
            return;
        }

        __size = other.__size;
        __cpy(other.__points);

    }
static void sub_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) {

  int i,j,k;

  EZ = EX;

  if (EX == EY) {
    i=j=k=p;
    Z[k] = Z[k+1] = ZERO; }
  else {
    j= EX - EY;
    if (j > p)  {__cpy(x,z,p);  return; }
    else {
      i=p;   j=p+1-j;   k=p;
      if (Y[j] > ZERO) {
        Z[k+1] = RADIX - Y[j--];
        Z[k]   = MONE; }
      else {
        Z[k+1] = ZERO;
        Z[k]   = ZERO;   j--;}
    }
  }

  for (; j>0; i--,j--) {
    Z[k] += (X[i] - Y[j]);
    if (Z[k] < ZERO) {
      Z[k]  += RADIX;
      Z[--k] = MONE; }
    else
      Z[--k] = ZERO;
  }

  for (; i>0; i--) {
    Z[k] += X[i];
    if (Z[k] < ZERO) {
      Z[k]  += RADIX;
      Z[--k] = MONE; }
    else
      Z[--k] = ZERO;
  }

  for (i=1; Z[i] == ZERO; i++) ;
  EZ = EZ - i + 1;
  for (k=1; i <= p+1; )
    Z[k++] = Z[i++];
  for (; k <= p; )
    Z[k++] = ZERO;

  return;
}
예제 #17
0
 Cluster& Cluster::operator=(const Cluster & other){
     if(__dimensionality != other.__dimensionality){
         throw DimensionalityMismatchEx(__dimensionality,other.__dimensionality);
     }
     if(this != &other){
         //delete & copy
         __id = other.__id;
         __size = other.__size;
         __del();
         if(other.__points != nullptr){
             __cpy(other.__points);
         }
         else{
             __points = nullptr;
         }
     }
     return *this;
 }
예제 #18
0
파일: mpatan.c 프로젝트: dreal/tai
void
SECTION
__mpatan(mp_no *x, mp_no *y, int p) {

  int i,m,n;
  double dx;
  mp_no
    mpone    = {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}},
    mptwo    = {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}},
    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 mpone, mptwo & 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;}
    }
    mpone.e    = mptwo.e    = mptwoim1.e = 1;
    mpone.d[0] = mpone.d[1] = mptwo.d[0] = mptwoim1.d[0] = ONE;
    mptwo.d[1] = TWO;

				 /* Reduce x m times */
    __mul(x,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] -= TWO;
      __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] = __atan_twom[m].d;
    __mul(&mptwoim1,&mpt,y,p);

  return;
}
예제 #19
0
Clustering::Cluster::Cluster(const Clustering::Cluster &cluster) {
    __cpy(cluster.__points, cluster.__size);
}
예제 #20
0
파일: mpexp.cpp 프로젝트: abma/streflop
void __mpexp(mp_no *x, mp_no *y, int p) {

  int i,j,k,m,m1,m2,n;
  Double a,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 mpone = {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 mpk   = {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,mpak,mpt1,mpt2;

  /* Choose m,n and compute a=2**(-m) */
  n = np[p];    m1 = m1p[p];    a = twomm1[p].d();
  for (i=0; i<EX; i++)  a *= RADIXI;
  for (   ; i>EX; i--)  a *= RADIX;
  b = X[1]*RADIXI;   m2 = 24*EX;
  for (; b<HALF; m2--)  { a *= TWO;   b *= TWO; }
  if (b == HALF) {
    for (i=2; i<=p; i++) { if (X[i]!=ZERO)  break; }
    if (i==p+1)  { m2--;  a *= TWO; }
  }
  if ((m=m1+m2) <= 0) {
    m=0;  a=ONE;
    for (i=n-1; i>0; i--,n--) { if (m1np[i][p]+m2>0)  break; }
  }

  /* Compute s=x*2**(-m). Put result in mps */
  __dbl_mp(a,&mpt1,p);
  __mul(x,&mpt1,&mps,p);

  /* Evaluate the polynomial. Put result in mpt2 */
  mpone.e=1;   mpone.d(0)=ONE;   mpone.d(1)=ONE;
  mpk.e = 1;   mpk.d(0) = ONE;   mpk.d(1)=nn[n].d();
  __dvd(&mps,&mpk,&mpt1,p);
  __add(&mpone,&mpt1,&mpak,p);
  for (k=n-1; k>1; k--) {
    __mul(&mps,&mpak,&mpt1,p);
    mpk.d(1)=nn[k].d();
    __dvd(&mpt1,&mpk,&mpt2,p);
    __add(&mpone,&mpt2,&mpak,p);
  }
  __mul(&mps,&mpak,&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; ) {
    __mul(&mpt2,&mpt2,&mpt1,p);  k++;
    if (k==m)  { j=1;  break; }
    __mul(&mpt1,&mpt1,&mpt2,p);  k++;
  }
  if (j)  __cpy(&mpt1,y,p);
  else    __cpy(&mpt2,y,p);
  return;
}
예제 #21
0
/* Add magnitudes of *X and *Y assuming that abs (*X) >= abs (*Y) > 0.  The
   sign of the sum *Z is not changed.  X and Y may overlap but not X and Z or
   Y and Z.  No guard digit is used.  The result equals the exact sum,
   truncated.  */
static void
SECTION
add_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p)
{
  long i, j, k;
  long p2 = p;
  mantissa_t zk;

  EZ = EX;

  i = p2;
  j = p2 + EY - EX;
  k = p2 + 1;

  if (__glibc_unlikely (j < 1))
    {
      __cpy (x, z, p);
      return;
    }

  zk = 0;

  for (; j > 0; i--, j--)
    {
      zk += X[i] + Y[j];
      if (zk >= RADIX)
	{
	  Z[k--] = zk - RADIX;
	  zk = 1;
	}
      else
	{
	  Z[k--] = zk;
	  zk = 0;
	}
    }

  for (; i > 0; i--)
    {
      zk += X[i];
      if (zk >= RADIX)
	{
	  Z[k--] = zk - RADIX;
	  zk = 1;
	}
      else
	{
	  Z[k--] = zk;
	  zk = 0;
	}
    }

  if (zk == 0)
    {
      for (i = 1; i <= p2; i++)
	Z[i] = Z[i + 1];
    }
  else
    {
      Z[1] = zk;
      EZ += 1;
    }
}
예제 #22
0
/* Subtract the magnitudes of *X and *Y assuming that abs (*x) > abs (*y) > 0.
   The sign of the difference *Z is not changed.  X and Y may overlap but not X
   and Z or Y and Z.  One guard digit is used.  The error is less than one
   ULP.  */
static void
SECTION
sub_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p)
{
  long i, j, k;
  long p2 = p;
  mantissa_t zk;

  EZ = EX;
  i = p2;
  j = p2 + EY - EX;
  k = p2;

  /* Y is too small compared to X, copy X over to the result.  */
  if (__glibc_unlikely (j < 1))
    {
      __cpy (x, z, p);
      return;
    }

  /* The relevant least significant digit in Y is non-zero, so we factor it in
     to enhance accuracy.  */
  if (j < p2 && Y[j + 1] > 0)
    {
      Z[k + 1] = RADIX - Y[j + 1];
      zk = -1;
    }
  else
    zk = Z[k + 1] = 0;

  /* Subtract and borrow.  */
  for (; j > 0; i--, j--)
    {
      zk += (X[i] - Y[j]);
      if (zk < 0)
	{
	  Z[k--] = zk + RADIX;
	  zk = -1;
	}
      else
	{
	  Z[k--] = zk;
	  zk = 0;
	}
    }

  /* We're done with digits from Y, so it's just digits in X.  */
  for (; i > 0; i--)
    {
      zk += X[i];
      if (zk < 0)
	{
	  Z[k--] = zk + RADIX;
	  zk = -1;
	}
      else
	{
	  Z[k--] = zk;
	  zk = 0;
	}
    }

  /* Normalize.  */
  for (i = 1; Z[i] == 0; i++)
    ;
  EZ = EZ - i + 1;
  for (k = 1; i <= p2 + 1; )
    Z[k++] = Z[i++];
  for (; k <= p2; )
    Z[k++] = 0;
}
예제 #23
0
파일: mpexp.c 프로젝트: AubrCool/glibc
/* 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;
}
예제 #24
0
 Cluster::Cluster(const Cluster & p) : __size(p.__size){
     __cpy(p.__points);
 }