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

📄 integer.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 4 页
字号:
    q = Icopy_one(q, samesign);  else if (yl == 1)  {    q = Icopy(q, x);    unscale(q->s, q->len, y->s[0], q->s);  }  else  {    IntRep* yy = 0;    IntRep* r  = 0;    unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));    if (prescale != 1 || y == q)    {      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 (!STATIC_IntRep(r)) delete r;  }  q->sgn = samesign;  Icheck(q);  return q;}IntRep* div(const IntRep* x, long y, IntRep* q){  nonnil(x);  int xl = x->len;  if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");  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)    q = Icopy_zero(q);  else if (comp == 0)  {    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 = (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 Integer& Ix, long y, Integer& Iq, long& rem){  const IntRep* x = Ix.rep;  nonnil(x);  IntRep* q = Iq.rep;  int xl = x->len;  if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");  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 = (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 Integer& Ix, const Integer& Iy, Integer& Iq, Integer& 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)("Integer", "attempted division by zero");  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 = (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)("Integer", "attempted division by zero");  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 = (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)("Integer", "attempted division by zero");  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 = (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 = ay / I_SHIFT;  int sw = 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;  if (newsgn = (y >= 0))    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)(Integer& x, long b){  if (b >= 0)  {    int bw = (unsigned long)b / I_SHIFT;    int sw = (unsigned long)b % I_SHIFT;

⌨️ 快捷键说明

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