⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 integer.cc

📁 Gambit 是一个游戏库理论软件
💻 CC
📖 第 1 页 / 共 5 页
字号:
    q = Icopy_one(q, samesign);  }  else if (yl == 1)  {    q = Icopy(q, x);    unscale(q->s, q->len, ys[0], q->s);  }  else  {    IntRep* r  = 0;	 unsigned short prescale = (unsigned short) (I_RADIX / (1 + ys[yl - 1]));    if (prescale != 1)    {      unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];      ys[0] = extract(prod);      prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];      ys[1] = extract(prod);      r = multiply(x, ((long)prescale & I_MAXNUM), r);    }    else    {      r = Icalloc(r, xl + 1);      scpy(x->s, r->s, xl);    }    int ql = xl - yl + 1;          q = Icalloc(q, ql);    do_divide(r->s, ys, yl, q->s, ql);    if (!STATIC_IntRep(r)) delete r;  }  q->sgn = samesign;  Icheck(q);  return q;}void divide(const gInteger& Ix, long y, gInteger& Iq, long& rem){  const IntRep* x = Ix.rep;  nonnil(x);  IntRep* q = Iq.rep;  int xl = x->len;  // if (y == 0) (*lib_error_handler)("gInteger", "attempted division by zero");  assert(y != 0);  unsigned short ys[SHORT_PER_LONG];  unsigned long u;  int ysgn = y >= 0;  if (ysgn)    u = y;  else    u = -y;  int yl = 0;  while (u != 0)  {    ys[yl++] = extract(u);    u = down(u);  }  int comp = xl - yl;  if (comp == 0) comp = docmp(x->s, ys, xl);  int xsgn = x->sgn;  int samesign = xsgn == ysgn;  if (comp < 0)  {    rem = Itolong(x);    q = Icopy_zero(q);  }  else if (comp == 0)  {    q = Icopy_one(q, samesign);    rem = 0;  }  else if (yl == 1)  {    q = Icopy(q, x);    rem = unscale(q->s, q->len, ys[0], q->s);  }  else  {    IntRep* r  = 0;	 unsigned short prescale = (unsigned short) (I_RADIX / (1 + ys[yl - 1]));    if (prescale != 1)    {      unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];      ys[0] = extract(prod);      prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];      ys[1] = extract(prod);      r = multiply(x, ((long)prescale & I_MAXNUM), r);    }    else    {      r = Icalloc(r, xl + 1);      scpy(x->s, r->s, xl);    }    int ql = xl - yl + 1;          q = Icalloc(q, ql);        do_divide(r->s, ys, yl, q->s, ql);    if (prescale != 1)    {      Icheck(r);      unscale(r->s, r->len, prescale, r->s);    }    Icheck(r);    rem = Itolong(r);    if (!STATIC_IntRep(r)) delete r;  }  rem = abs(rem);  if (xsgn == I_NEGATIVE) rem = -rem;  q->sgn = samesign;  Icheck(q);  Iq.rep = q;}void divide(const gInteger& Ix, const gInteger& Iy, gInteger& Iq, gInteger& Ir){  const IntRep* x = Ix.rep;  nonnil(x);  const IntRep* y = Iy.rep;  nonnil(y);  IntRep* q = Iq.rep;  IntRep* r = Ir.rep;  int xl = x->len;  int yl = y->len;  /* if (yl == 0)    (*lib_error_handler)("gInteger", "attempted division by zero");  */  assert(yl != 0);  int comp = ucompare(x, y);  int xsgn = x->sgn;  int ysgn = y->sgn;  int samesign = xsgn == ysgn;  if (comp < 0)  {    q = Icopy_zero(q);    r = Icopy(r, x);  }  else if (comp == 0)  {    q = Icopy_one(q, samesign);    r = Icopy_zero(r);  }  else if (yl == 1)  {    q = Icopy(q, x);    int rem =  unscale(q->s, q->len, y->s[0], q->s);    r = Icopy_long(r, rem);    if (rem != 0)      r->sgn = xsgn;  }  else  {    IntRep* yy = 0;	 unsigned short prescale = (unsigned short) (I_RADIX / (1 + y->s[yl - 1]));    if (prescale != 1 || y == q || y == r)    {      yy = multiply(y, ((long)prescale & I_MAXNUM), yy);      r = multiply(x, ((long)prescale & I_MAXNUM), r);    }    else    {      yy = (IntRep*)y;      r = Icalloc(r, xl + 1);      scpy(x->s, r->s, xl);    }    int ql = xl - yl + 1;          q = Icalloc(q, ql);    do_divide(r->s, yy->s, yl, q->s, ql);    if (yy != y && !STATIC_IntRep(yy)) delete yy;    if (prescale != 1)    {      Icheck(r);      unscale(r->s, r->len, prescale, r->s);    }  }  q->sgn = samesign;  Icheck(q);  Iq.rep = q;  Icheck(r);  Ir.rep = r;}IntRep* mod(const IntRep* x, const IntRep* y, IntRep* r){  nonnil(x);  nonnil(y);  int xl = x->len;  int yl = y->len;  // if (yl == 0) (*lib_error_handler)("gInteger", "attempted division by zero");  assert(yl != 0);  int comp = ucompare(x, y);  int xsgn = x->sgn;  if (comp < 0)    r = Icopy(r, x);  else if (comp == 0)    r = Icopy_zero(r);  else if (yl == 1)  {    int rem = unscale(x->s, xl, y->s[0], 0);    r = Icopy_long(r, rem);    if (rem != 0)      r->sgn = xsgn;  }  else  {    IntRep* yy = 0;	 unsigned short prescale = (unsigned short) (I_RADIX / (1 + y->s[yl - 1]));    if (prescale != 1 || y == r)    {      yy = multiply(y, ((long)prescale & I_MAXNUM), yy);      r = multiply(x, ((long)prescale & I_MAXNUM), r);    }    else    {      yy = (IntRep*)y;      r = Icalloc(r, xl + 1);      scpy(x->s, r->s, xl);    }          do_divide(r->s, yy->s, yl, 0, xl - yl + 1);    if (yy != y && !STATIC_IntRep(yy)) delete yy;    if (prescale != 1)    {      Icheck(r);      unscale(r->s, r->len, prescale, r->s);    }  }  Icheck(r);  return r;}IntRep* mod(const IntRep* x, long y, IntRep* r){  nonnil(x);  int xl = x->len;  // if (y == 0) (*lib_error_handler)("gInteger", "attempted division by zero");  assert(y != 0);  unsigned short ys[SHORT_PER_LONG];  unsigned long u;  int ysgn = y >= 0;  if (ysgn)    u = y;  else    u = -y;  int yl = 0;  while (u != 0)  {    ys[yl++] = extract(u);    u = down(u);  }  int comp = xl - yl;  if (comp == 0) comp = docmp(x->s, ys, xl);  int xsgn = x->sgn;  if (comp < 0)    r = Icopy(r, x);  else if (comp == 0)    r = Icopy_zero(r);  else if (yl == 1)  {    int rem = unscale(x->s, xl, ys[0], 0);    r = Icopy_long(r, rem);    if (rem != 0)      r->sgn = xsgn;  }  else  {	 unsigned short prescale = (unsigned short) (I_RADIX / (1 + ys[yl - 1]));    if (prescale != 1)    {      unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];      ys[0] = extract(prod);      prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];      ys[1] = extract(prod);      r = multiply(x, ((long)prescale & I_MAXNUM), r);    }    else    {      r = Icalloc(r, xl + 1);      scpy(x->s, r->s, xl);    }          do_divide(r->s, ys, yl, 0, xl - yl + 1);    if (prescale != 1)    {      Icheck(r);      unscale(r->s, r->len, prescale, r->s);    }  }  Icheck(r);  return r;}IntRep* lshift(const IntRep* x, long y, IntRep* r){  nonnil(x);  int xl = x->len;  if (xl == 0 || y == 0)  {    r = Icopy(r, x);    return r;  }  int xrsame = x == r;  int rsgn = x->sgn;  long ay = (y < 0)? -y : y;  int bw = (int) (ay / I_SHIFT);  int sw = (int) (ay % I_SHIFT);  if (y > 0)  {    int rl = bw + xl + 1;    if (xrsame)      r = Iresize(r, rl);    else      r = Icalloc(r, rl);    unsigned short* botr = r->s;    unsigned short* rs = &(botr[rl - 1]);    const unsigned short* botx = (xrsame)? botr : x->s;    const unsigned short* xs = &(botx[xl - 1]);    unsigned long a = 0;    while (xs >= botx)    {      a = up(a) | ((unsigned long)(*xs--) << sw);      *rs-- = extract(down(a));    }    *rs-- = extract(a);    while (rs >= botr)      *rs-- = 0;  }  else  {    int rl = xl - bw;    if (rl < 0)      r = Icopy_zero(r);    else    {      if (xrsame)        r = Iresize(r, rl);      else        r = Icalloc(r, rl);      int rw = I_SHIFT - sw;      unsigned short* rs = r->s;      unsigned short* topr = &(rs[rl]);      const unsigned short* botx = (xrsame)? rs : x->s;      const unsigned short* xs =  &(botx[bw]);      const unsigned short* topx = &(botx[xl]);      unsigned long a = (unsigned long)(*xs++) >> sw;      while (xs < topx)      {        a |= (unsigned long)(*xs++) << rw;        *rs++ = extract(a);        a = down(a);      }      *rs++ = extract(a);      if (xrsame) topr = (unsigned short*)topx;      while (rs < topr)        *rs++ = 0;    }  }  r->sgn = rsgn;  Icheck(r);  return r;}IntRep* lshift(const IntRep* x, const IntRep* yy, int negatey, IntRep* r){  long y = Itolong(yy);  if (negatey)    y = -y;  return lshift(x, y, r);}IntRep* bitop(const IntRep* x, const IntRep* y, IntRep* r, char op){  nonnil(x);  nonnil(y);  int xl = x->len;  int yl = y->len;  int xsgn = x->sgn;  int xrsame = x == r;  int yrsame = y == r;  if (xrsame || yrsame)    r = Iresize(r, calc_len(xl, yl, 0));  else    r = Icalloc(r, calc_len(xl, yl, 0));  r->sgn = xsgn;  unsigned short* rs = r->s;  unsigned short* topr = &(rs[r->len]);  const unsigned short* as;  const unsigned short* bs;  const unsigned short* topb;  if (xl >= yl)  {    as = (xrsame)? rs : x->s;    bs = (yrsame)? rs : y->s;    topb = &(bs[yl]);  }  else  {    bs = (xrsame)? rs : x->s;    topb = &(bs[xl]);    as = (yrsame)? rs : y->s;  }  switch (op)  {  case '&':    while (bs < topb) *rs++ = *as++ & *bs++;    while (rs < topr) *rs++ = 0;    break;  case '|':    while (bs < topb) *rs++ = *as++ | *bs++;    while (rs < topr) *rs++ = *as++;    break;  case '^':    while (bs < topb) *rs++ = *as++ ^ *bs++;    while (rs < topr) *rs++ = *as++;    break;  }  Icheck(r);  return r;}IntRep* bitop(const IntRep* x, long y, IntRep* r, char op){  nonnil(x);  unsigned short tmp[SHORT_PER_LONG];  unsigned long u;  int newsgn = (y >= 0);  if (newsgn)	 u = y;  else	 u = -y;  int l = 0;  while (u != 0)  {	 tmp[l++] = extract(u);	 u = down(u);  }  int xl = x->len;  int yl = l;  int xsgn = x->sgn;  int xrsame = x == r;  if (xrsame)	 r = Iresize(r, calc_len(xl, yl, 0));  else	 r = Icalloc(r, calc_len(xl, yl, 0));  r->sgn = xsgn;  unsigned short* rs = r->s;  unsigned short* topr = &(rs[r->len]);  const unsigned short* as;  const unsigned short* bs;  const unsigned short* topb;  if (xl >= yl)  {	 as = (xrsame)? rs : x->s;	 bs = tmp;	 topb = &(bs[yl]);  }  else  {	 bs = (xrsame)? rs : x->s;	 topb = &(bs[xl]);	 as = tmp;  }  switch (op)  {  case '&':	 while (bs < topb) *rs++ = *as++ & *bs++;	 while (rs < topr) *rs++ = 0;	 break;  case '|':	 while (bs < topb) *rs++ = *as++ | *bs++;	 while (rs < topr) *rs++ = *as++;	 break;  case '^':	 while (bs < topb) *rs++ = *as++ ^ *bs++;	 while (rs < topr) *rs++ = *as++;	 break;  }  Icheck(r);  return r;}IntRep*  Compl(const IntRep* src, IntRep* r){  nonnil(src);  r = Icopy(r, src);  unsigned short* s = r->s;  unsigned short* top = &(s[r->len - 1]);  while (s < top)  {    unsigned short cmp = ~(*s);    *s++ = cmp;  }  unsigned short a = *s;  unsigned short b = 0;  while (a != 0)  {    b <<= 1;    if (!(a & 1)) b |= 1;    a >>= 1;  }  *s = b;  Icheck(r);  return r;}void (setbit)(gInteger& x, long b){  if (b >= 0)  {	 int bw = (int) ((unsigned long)b / I_SHIFT);	 int sw = (int) ((unsigned long)b % I_SHIFT);    int xl = x.rep ? x.rep->len : 0;    if (xl <= bw)      x.rep = Iresize(x.rep, calc_len(xl, bw+1, 0));    x.rep->s[bw] |= (1 << sw);    Icheck(x.rep);  }}void clearbit(gInteger& x, long b){  if (b >= 0)    {      if (x.rep == 0)	x.rep = &_ZeroRep;      else	{	  int bw = (int) ((unsigned long)b / I_SHIFT);	  int sw = (int) ((unsigned long)b % I_SHIFT);	  if (x.rep->len > bw)	    x.rep->s[bw] &= ~(1 << sw);	}    Icheck(x.rep);  }}int testbit(const gInteger& x, long b){  if (x.rep != 0 && b >= 0)  {	 int bw = (int) ((unsigned long)b / I_SHIFT);	 int sw = (int) ((unsigned long)b % I_SHIFT);    return (bw < x.rep->len && (x.rep->s[bw] & (1 << sw)) != 0);  }  else    return 0;}// A  version of knuth's algorithm B / ex. 4.5.3.34// A better version that doesn't bother shifting all of `t' forthcomingIntRep* gcd(const IntRep* x, const IntRep* y){  nonnil(x);  nonnil(y);  int ul = x->len;  int vl = y->len;    if (vl == 0)    return Ialloc(0, x->s, ul, I_POSITIVE, ul);  else if (ul == 0)    return Ialloc(0, y->s, vl, I_POSITIVE, vl);  IntRep* u = Ialloc(0, x->s, ul, I_POSITIVE, ul);  IntRep* v = Ialloc(0, y->s, vl, I_POSITIVE, vl);// find shift so that both not even  long k = 0;  int l = (ul <= vl)? ul : vl;  int cont = 1, i;  for (i = 0;  i < l && cont; ++i)  {    unsigned long a =  (i < ul)? u->s[i] : 0;    unsigned long b =  (i < vl)? v->s[i] : 0;    for (unsigned int j = 0; j < I_SHIFT; ++j)    {      if ((a | b) & 1)      {        cont = 0;        break;      }      else      {        ++k;        a >>= 1;        b >>= 1;      }    }  }  if (k != 0)  {    u = lshift(u, -k, u);    v = lshift(v, -k, v);  }  IntRep* t;  if (u->s[0] & 01)    t = Ialloc(0, v->s, v->len, !v->sgn, v->len);  else    t = Ialloc(0, u->s, u->len, u->sgn, u->len);  while (t->len != 0)  {    long s = 0;                 // shift t until odd    cont = 1;    int tl = t->len;    for (i = 0; i < tl && cont; ++i)    {      unsigned long a = t->s[i];      for (unsigned int j = 0; j < I_SHIFT; ++j)      {        if (a & 1)        {          cont = 0;          break;        }        else        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -