Annotation of researchv10no/libmp/bundled, revision 1.1.1.1

1.1       root        1: # To unbundle, sh this file
                      2: echo gcd.c 1>&2
                      3: sed 's/.//' >gcd.c <<'//GO.SYSIN DD gcd.c'
                      4: -#include "mp.h"
                      5: -mgcd(a,b,c) mint *a,*b,*c;
                      6: -{     mint *x,*y,*z,*w;
                      7: -      x = itom(0), y = itom(0), z = itom(0), w = itom(0);
                      8: -      move(a,x);
                      9: -      move(b,y);
                     10: -      while(y->len!=0){
                     11: -              mdiv(x,y,w,z);
                     12: -              move(y,x);
                     13: -              move(z,y);
                     14: -      }
                     15: -      move(x,c);
                     16: -      mfree(x);
                     17: -      mfree(y);
                     18: -      mfree(z);
                     19: -      mfree(w);
                     20: -}
                     21: -invert(a, b, c) mint *a, *b, *c;
                     22: -{     mint x, y, z, w, Anew, Aold;
                     23: -      int i = 0;
                     24: -      x.len = y.len = z.len = w.len = Aold.len = 0;
                     25: -      Anew.len = 1;
                     26: -      Anew.val = xalloc(1, "invert");
                     27: -      *Anew.val = 1;
                     28: -      move(b, &x);
                     29: -      move(a, &y);
                     30: -      while(y.len != 0)
                     31: -      {       mdiv(&x, &y, &w, &z);
                     32: -              move(&Anew, &x);
                     33: -              mult(&w, &Anew, &Anew);
                     34: -              madd(&Anew, &Aold, &Anew);
                     35: -              move(&x, &Aold);
                     36: -              move(&y, &x);
                     37: -              move(&z, &y);
                     38: -              i++;
                     39: -      }
                     40: -      move(&Aold, c);
                     41: -      if( (i&01) == 0) msub(b, c, c);
                     42: -      xfree(&x);
                     43: -      xfree(&y);
                     44: -      xfree(&z);
                     45: -      xfree(&w);
                     46: -      xfree(&Aold);
                     47: -      xfree(&Anew);
                     48: -}
                     49: -
                     50: -lineq(a, b, x, y, u)  /* ax + by = u */
                     51: -mint *a, *b, *x, *u, *y;
                     52: -{     mint *at, *bt, *xo, *yo, *q, *r, *z;
                     53: -      static mint *zero, *one;
                     54: -      int i;
                     55: -      at = itom(0), bt = itom(0), xo = itom(0);
                     56: -      yo = itom(0), q = itom(0), r = itom(0), z = itom(0);
                     57: -      if(zero == 0) zero = itom(0);
                     58: -      if(one == 0) one = itom(1);
                     59: -      move(a, at);
                     60: -      move(b, bt);
                     61: -      move(zero, x);
                     62: -      move(one, xo);
                     63: -      move(zero, yo);
                     64: -      move(one, y);
                     65: -      if(bt->len == 0) {
                     66: -              move(one, x);
                     67: -              move(zero, y);
                     68: -              move(a, u);
                     69: -              goto out;
                     70: -      }
                     71: -      for(i = 0; ; i++) {
                     72: -              mdiv(at, bt, q, r);
                     73: -              if(r->len == 0)
                     74: -                      break;
                     75: -              move(xo, z);
                     76: -              move(x, xo);
                     77: -              mult(q, xo, x);
                     78: -              madd(z, x, x);
                     79: -              move(yo, z);
                     80: -              move(y, yo);
                     81: -              mult(q, yo, y);
                     82: -              madd(z, y, y);
                     83: -              move(bt, at);
                     84: -              move(r, bt);
                     85: -      }
                     86: -      move(bt, u);
                     87: -      if(i & 1)
                     88: -              y->len = -y->len;
                     89: -      else
                     90: -              x->len = -x->len;
                     91: -out:
                     92: -      mfree(z), mfree(r), mfree(q), mfree(yo);
                     93: -      mfree(xo), mfree(bt), mfree(at);
                     94: -}
                     95: //GO.SYSIN DD gcd.c
                     96: echo halloc.c 1>&2
                     97: sed 's/.//' >halloc.c <<'//GO.SYSIN DD halloc.c'
                     98: -/* list allocator */
                     99: -
                    100: -typedef struct hdr {
                    101: -      struct hdr *next;
                    102: -      struct hdr **list;
                    103: -      short d[1];
                    104: -} hdr;
                    105: -extern char *malloc();
                    106: -
                    107: -hdr *h1, *h4, *h6;
                    108: -
                    109: -hfree(d)
                    110: -short *d;
                    111: -{     hdr *p;
                    112: -      if(d == (short *)1)
                    113: -              return;
                    114: -      p = (hdr *)((char *)d - 2 * sizeof(hdr *));
                    115: -      if(p->list == 0) {
                    116: -              free((char *)p);
                    117: -              return;
                    118: -      }
                    119: -      p->next = *p->list;
                    120: -      *p->list = p;
                    121: -}
                    122: -
                    123: -short *
                    124: -halloc(n)
                    125: -{     short *x;
                    126: -      hdr *p;
                    127: -      if(n <= 0)
                    128: -              return((short *)1);     /* and unusable */
                    129: -      if(n <= 2) {
                    130: -              if(!h1)
                    131: -                      makelist(4, &h1);
                    132: -              x = h1->d;
                    133: -              h1 = h1->next;
                    134: -              return(x);
                    135: -      }
                    136: -      if(n <= 8) {
                    137: -              if(!h4)
                    138: -                      makelist(16, &h4);
                    139: -              x = h4->d;
                    140: -              h4 = h4->next;
                    141: -              return(x);
                    142: -      }
                    143: -      if(n <= 64) {
                    144: -              if(!h6)
                    145: -                      makelist(128, &h6);
                    146: -              x = h6->d;
                    147: -              h6 = h6->next;
                    148: -              return(x);
                    149: -      }
                    150: -      p = (hdr *) malloc(sizeof(hdr) + (n - 1) * sizeof(short));
                    151: -      p->list = 0;
                    152: -      return(p->d);
                    153: -}
                    154: -
                    155: -makelist(n, p)
                    156: -hdr **p;
                    157: -{     int i, d;
                    158: -      char *s;
                    159: -      hdr *h;
                    160: -      d = sizeof(hdr) + sizeof(short) * (n-1);
                    161: -      d = (d + 3) & (~3);
                    162: -      s = malloc(128 * d);
                    163: -      h = *p = (hdr *)s;
                    164: -      for(i = 0; i < 127; i++) {
                    165: -              h->next = (hdr *)(s + d);
                    166: -              h->list = p;
                    167: -              s += d;
                    168: -              h = (hdr *)s;
                    169: -      }
                    170: -      h->next = 0;
                    171: -      h->list = p;
                    172: -}
                    173: //GO.SYSIN DD halloc.c
                    174: echo madd.c 1>&2
                    175: sed 's/.//' >madd.c <<'//GO.SYSIN DD madd.c'
                    176: -#include "mp.h"
                    177: -m_add(a,b,c) mint *a,*b,*c;
                    178: -{     register int carry,i;
                    179: -      register int x;
                    180: -      register short *cval;
                    181: -      cval=xalloc(a->len+1,"m_add");
                    182: -      carry=0;
                    183: -      for(i=0;i<b->len;i++)
                    184: -      {       x=carry+a->val[i]+b->val[i];
                    185: -              if(x&0100000)
                    186: -              {       carry=1;
                    187: -                      cval[i]=x&077777;
                    188: -              }
                    189: -              else
                    190: -              {       carry=0;
                    191: -                      cval[i]=x;
                    192: -              }
                    193: -      }
                    194: -      for(;i<a->len;i++)
                    195: -      {       x=carry+a->val[i];
                    196: -              if(x&0100000) cval[i]=x&077777;
                    197: -              else
                    198: -              {       carry=0;
                    199: -                      cval[i]=x;
                    200: -              }
                    201: -
                    202: -      }
                    203: -      if(carry==1)
                    204: -      {       cval[i]=1;
                    205: -              c->len=i+1;
                    206: -      }
                    207: -      else c->len=a->len;
                    208: -      c->val=cval;
                    209: -      if(c->len==0) shfree(cval);
                    210: -      return;
                    211: -}
                    212: -madd(a,b,c) mint *a,*b,*c;
                    213: -{     mint x,y,z;
                    214: -      int sign;
                    215: -      x.len=a->len;
                    216: -      x.val=a->val;
                    217: -      y.len=b->len;
                    218: -      y.val=b->val;
                    219: -      z.len=0;
                    220: -      sign=1;
                    221: -      if(x.len>=0)
                    222: -              if(y.len>=0)
                    223: -                      if(x.len>=y.len) m_add(&x,&y,&z);
                    224: -                      else m_add(&y,&x,&z);
                    225: -              else
                    226: -              {       y.len= -y.len;
                    227: -                      msub(&x,&y,&z);
                    228: -              }
                    229: -      else    if(y.len<=0)
                    230: -              {       x.len = -x.len;
                    231: -                      y.len= -y.len;
                    232: -                      sign= -1;
                    233: -                      madd(&x,&y,&z);
                    234: -              }
                    235: -              else
                    236: -              {       x.len= -x.len;
                    237: -                      msub(&y,&x,&z);
                    238: -              }
                    239: -       xfree(c);
                    240: -      c->val=z.val;
                    241: -      c->len=sign*z.len;
                    242: -      return;
                    243: -}
                    244: -m_sub(a,b,c) mint *a,*b,*c;
                    245: -{     register int x,i;
                    246: -      register int borrow;
                    247: -      short one;
                    248: -      mint mone;
                    249: -      one=1; mone.len= 1; mone.val= &one;
                    250: -      c->val=xalloc(a->len,"m_sub");
                    251: -      borrow=0;
                    252: -      for(i=0;i<b->len;i++)
                    253: -      {       x=borrow+a->val[i]-b->val[i];
                    254: -              if(x&0100000)
                    255: -              {       borrow= -1;
                    256: -                      c->val[i]=x&077777;
                    257: -              }
                    258: -              else
                    259: -              {       borrow=0;
                    260: -                      c->val[i]=x;
                    261: -              }
                    262: -      }
                    263: -      for(;i<a->len;i++)
                    264: -      {       x=borrow+a->val[i];
                    265: -              if(x&0100000) c->val[i]=x&077777;
                    266: -              else
                    267: -              {       borrow=0;
                    268: -                      c->val[i]=x;
                    269: -              }
                    270: -      }
                    271: -      if(borrow<0)
                    272: -      {       for(i=0;i<a->len;i++) c->val[i] ^= 077777;
                    273: -              c->len=a->len;
                    274: -              madd(c,&mone,c);
                    275: -      }
                    276: -      for(i=a->len-1;i>=0;--i)
                    277: -              if(c->val[i]>0) {
                    278: -                      if(borrow==0) c->len=i+1;
                    279: -                      else c->len= -i-1;
                    280: -                      return;
                    281: -              }
                    282: -      shfree(c->val);
                    283: -      return;
                    284: -}
                    285: -msub(a,b,c) mint *a,*b,*c;
                    286: -{     mint x,y,z;
                    287: -      int sign;
                    288: -      x.len=a->len;
                    289: -      y.len=b->len;
                    290: -      x.val=a->val;
                    291: -      y.val=b->val;
                    292: -      z.len=0;
                    293: -      sign=1;
                    294: -      if(x.len>=0)
                    295: -              if(y.len>=0)
                    296: -                      if(x.len>=y.len) m_sub(&x,&y,&z);
                    297: -                      else
                    298: -                      {       sign= -1;
                    299: -                              msub(&y,&x,&z);
                    300: -                      }
                    301: -              else
                    302: -              {       y.len= -y.len;
                    303: -                      madd(&x,&y,&z);
                    304: -              }
                    305: -      else    if(y.len<=0)
                    306: -              {       sign= -1;
                    307: -                      x.len= -x.len;
                    308: -                      y.len= -y.len;
                    309: -                      msub(&x, &y, &z);
                    310: -              }
                    311: -              else
                    312: -              {       x.len= -x.len;
                    313: -                      madd(&x,&y,&z);
                    314: -                      sign= -1;
                    315: -              }
                    316: -      if(a==c && x.len!=0) xfree(a);
                    317: -      else if(b==c && y.len!=0) xfree(b);
                    318: -      else xfree(c);
                    319: -      c->val=z.val;
                    320: -      c->len=sign*z.len;
                    321: -      return;
                    322: -}
                    323: //GO.SYSIN DD madd.c
                    324: echo mdiv.c 1>&2
                    325: sed 's/.//' >mdiv.c <<'//GO.SYSIN DD mdiv.c'
                    326: -#include "mp.h"
                    327: -int mpdivdebug;
                    328: -mdiv(a,b,q,r) mint *a,*b,*q,*r;
                    329: -{     mint *x,*y, *z;
                    330: -      int alen, blen;
                    331: -      x = itom(0), y = itom(0);
                    332: -      z = itom(0);
                    333: -      move(a, x);
                    334: -      move(b, y);
                    335: -      alen = x->len;
                    336: -      if(x->len<0) {x->len= -x->len;}
                    337: -      blen = y->len;
                    338: -      if(y->len<0) {y->len= -y->len;}
                    339: -      xfree(q);
                    340: -      xfree(r);
                    341: -      m_div(x,y,q,r);
                    342: -      if(mpdivdebug) {
                    343: -              mult(y, q, z);
                    344: -              madd(z, r, z);
                    345: -              if(mcmp(z, x) != 0) {
                    346: -                      mout(a);
                    347: -                      mout(b);
                    348: -                      fatal("mdiv err");
                    349: -              }
                    350: -      }
                    351: -      if(alen < 0) {
                    352: -              mint o;
                    353: -              short i = 1;
                    354: -              o.len = 1;
                    355: -              o.val = &i;
                    356: -              if(r->len == 0) {
                    357: -                      if(blen > 0)
                    358: -                              q->len = -q->len;
                    359: -                      goto out;
                    360: -              }
                    361: -              msub(r, y, r);
                    362: -              r->len = -r->len;
                    363: -              madd(q, &o, q);
                    364: -              if(blen > 0)
                    365: -                      q->len = -q->len;
                    366: -              goto out;
                    367: -      }
                    368: -      if(blen < 0)
                    369: -              q->len = -q->len;
                    370: -out:
                    371: -      mfree(z);
                    372: -      mfree(y);
                    373: -      mfree(x);
                    374: -}
                    375: -#ifdef vax
                    376: -union zz {
                    377: -      long a;
                    378: -      struct {
                    379: -              unsigned int lo:15, hi:15;
                    380: -      } b;
                    381: -};
                    382: -#endif
                    383: -m_dsb(q,n,a,b) short *a,*b;
                    384: -{     long int qx, u;
                    385: -      union zz x;
                    386: -      int borrow,j;
                    387: -      qx=q;
                    388: -      x.a = 0;
                    389: -      for(j = 0; j < n; j++) {
                    390: -              x.a = qx * a[j] + x.b.hi;
                    391: -              if((b[j] -= x.b.lo) < 0) {
                    392: -                      b[j] += (1 << 15);
                    393: -                      x.b.hi += 1;
                    394: -              }
                    395: -      }
                    396: -      if((b[j] -= x.b.hi) >= 0)
                    397: -              return(0);
                    398: -      borrow=0;
                    399: -      for(j=0;j<n;j++)
                    400: -      {       u=a[j]+b[j]+borrow;
                    401: -              if(u & 0100000)
                    402: -                      borrow = 1;
                    403: -              else borrow=0;
                    404: -              b[j]=u&077777;
                    405: -      }
                    406: -      { return(1);}
                    407: -}
                    408: -m_trq(v1,v2,u1,u2,u3)
                    409: -{     long int d;
                    410: -      long int x1;
                    411: -      if(u1==v1) d=077777;
                    412: -      else d=(u1*0100000L+u2)/v1;
                    413: -      while(1)
                    414: -      {       x1=u1*0100000L+u2-v1*d;
                    415: -              x1=x1*0100000L+u3-v2*d;
                    416: -              if(x1<0) d=d-1;
                    417: -              else {return(d);}
                    418: -      }
                    419: -}
                    420: -m_div(a,b,q,r) mint *a,*b,*q,*r;
                    421: -{     mint u,v,x,w;
                    422: -      short d,*qval;
                    423: -      int qq,n,v1,v2,j;
                    424: -      u.len=v.len=x.len=w.len=0;
                    425: -      if(b->len==0) { fatal("mdiv divide by zero"); return;}
                    426: -      if(b->len==1)
                    427: -      {       r->val=xalloc(1,"m_div1");
                    428: -              sdiv(a,b->val[0],q,r->val);
                    429: -              if(r->val[0]==0)
                    430: -              {       shfree(r->val);
                    431: -                      r->len=0;
                    432: -              }
                    433: -              else r->len=1;
                    434: -              return;
                    435: -      }
                    436: -      if(a->len < b->len)
                    437: -      {       q->len=0;
                    438: -              r->len=a->len;
                    439: -              r->val=xalloc(r->len,"m_div2");
                    440: -              for(qq=0;qq<r->len;qq++) r->val[qq]=a->val[qq];
                    441: -              return;
                    442: -      }
                    443: -      x.len=1;
                    444: -      x.val = &d;
                    445: -      n=b->len;
                    446: -      d=0100000L/(b->val[n-1]+1L);
                    447: -      mult(a,&x,&u); /*subtle: relies on fact that mult allocates extra space */
                    448: -      mult(b,&x,&v);
                    449: -      v1=v.val[n-1];
                    450: -      v2=v.val[n-2];
                    451: -      qval=xalloc(a->len-n+1,"m_div3");
                    452: -      for(j=a->len-n;j>=0;j--)
                    453: -      {       qq=m_trq(v1,v2,u.val[j+n],u.val[j+n-1],u.val[j+n-2]);
                    454: -              if(m_dsb(qq,n,v.val,&(u.val[j]))) qq -= 1;
                    455: -              qval[j]=qq;
                    456: -      }
                    457: -      x.len=n;
                    458: -      x.val=u.val;
                    459: -      mcan(&x);
                    460: -      sdiv(&x,d,&w,(short *)&qq);
                    461: -      r->len=w.len;
                    462: -      r->val=w.val;
                    463: -      q->val=qval;
                    464: -      qq=a->len-n+1;
                    465: -      if(qq>0 && qval[qq-1]==0) qq -= 1;
                    466: -      q->len=qq;
                    467: -      if(qq==0) shfree(qval);
                    468: -      if(x.len!=0) xfree(&u);
                    469: -      xfree(&v);
                    470: -      return;
                    471: -}
                    472: //GO.SYSIN DD mdiv.c
                    473: echo mout.c 1>&2
                    474: sed 's/.//' >mout.c <<'//GO.SYSIN DD mout.c'
                    475: -#include <stdio.h>
                    476: -#include "mp.h"
                    477: -m_in(a,b,f) mint *a; FILE *f;
                    478: -{     mint x,y,ten;
                    479: -      int sign,c;
                    480: -      short qten,qy;
                    481: -      xfree(a);
                    482: -      sign=1;
                    483: -      ten.len=1;
                    484: -      ten.val= &qten;
                    485: -      qten=b;
                    486: -      x.len=0;
                    487: -      y.len=1;
                    488: -      y.val= &qy;
                    489: -      while((c=getc(f))!=EOF)
                    490: -      switch(c)
                    491: -      {
                    492: -      case '\\':      getc(f);
                    493: -              continue;
                    494: -      case '\t':
                    495: -      case '\n':
                    496: -              goto done;
                    497: -      case ' ':
                    498: -              continue;
                    499: -      case '-': sign = -sign;
                    500: -              continue;
                    501: -      default: if(c>='0' && c<= '9')
                    502: -              {       qy=c-'0';
                    503: -                      mult(&x,&ten,a);
                    504: -                      madd(a,&y,a);
                    505: -                      move(a,&x);
                    506: -                      continue;
                    507: -              }
                    508: -              else
                    509: -              {       (void) ungetc(c,stdin);
                    510: -done:
                    511: -                      a->len *= sign;
                    512: -                      mcan(a);
                    513: -                      return(0);
                    514: -              }
                    515: -      }
                    516: -      return(EOF);
                    517: -}
                    518: -m_out(a,b,f) mint *a; FILE *f;
                    519: -{     int sign,xlen,i;
                    520: -      short r;
                    521: -      mint x;
                    522: -      char *obuf;
                    523: -      register char *bp;
                    524: -      sign=1;
                    525: -      xlen=a->len;
                    526: -      if(xlen<0)
                    527: -      {       xlen= -xlen;
                    528: -              sign= -1;
                    529: -      }
                    530: -      if(xlen==0)
                    531: -      {       fprintf(f,"0\n");
                    532: -              return;
                    533: -      }
                    534: -      x.len=xlen;
                    535: -      x.val=xalloc(xlen,"m_out");
                    536: -      for(i=0;i<xlen;i++) x.val[i]=a->val[i];
                    537: -      obuf=(char *)malloc(7*xlen);
                    538: -      bp=obuf+7*xlen-1;
                    539: -      *bp--=0;
                    540: -      while(x.len>0)
                    541: -      {       for(i=0;i<10&&x.len>0;i++)
                    542: -              {       sdiv(&x,b,&x,&r);
                    543: -                      *bp--=r+'0';
                    544: -              }
                    545: -              if(x.len>0) *bp--=' ';
                    546: -      }
                    547: -      if(sign==-1) *bp--='-';
                    548: -      fprintf(f,"%s\n",bp+1);
                    549: -      free(obuf);
                    550: -      xfree(&x);
                    551: -      return;
                    552: -}
                    553: -sdiv(a,n,q,r) mint *a,*q; short *r;
                    554: -{     mint x,y;
                    555: -      int sign;
                    556: -      sign=1;
                    557: -      x.len=a->len;
                    558: -      x.val=a->val;
                    559: -      if(n<0) {
                    560: -              sign= -sign;
                    561: -              n= -n;
                    562: -      }
                    563: -      if(x.len<0) {
                    564: -              sign = -sign;
                    565: -              x.len= -x.len;
                    566: -      }
                    567: -      else if(x.len == 0) {
                    568: -              xfree(q);
                    569: -              *r = 0;
                    570: -              return;
                    571: -      }
                    572: -      s_div(&x,n,&y,r);
                    573: -      xfree(q);
                    574: -      q->val=y.val;
                    575: -      q->len=sign*y.len;
                    576: -      *r = *r*sign;
                    577: -      return;
                    578: -}
                    579: -s_div(a,n,q,r) mint *a,*q; short *r;
                    580: -{     int qlen,i;
                    581: -      long int x;
                    582: -      short *qval;
                    583: -      x=0;
                    584: -      qlen=a->len;
                    585: -      qval=xalloc(qlen,"s_div");
                    586: -      for(i=qlen-1;i>=0;i--)
                    587: -      {
                    588: -              x=x*0100000L+a->val[i];
                    589: -              qval[i]=x/n;
                    590: -              x=x%n;
                    591: -      }
                    592: -      *r=x;
                    593: -      if(qval[qlen-1]==0) qlen--;
                    594: -      q->len=qlen;
                    595: -      q->val=qval;
                    596: -      if(qlen==0) shfree(qval);
                    597: -      return;
                    598: -}
                    599: -min(a) mint *a;
                    600: -{
                    601: -      return(m_in(a,10,stdin));
                    602: -}
                    603: -omin(a) mint *a;
                    604: -{
                    605: -      return(m_in(a,8,stdin));
                    606: -}
                    607: -mout(a) mint *a;
                    608: -{
                    609: -      m_out(a,10,stdout);
                    610: -}
                    611: -omout(a) mint *a;
                    612: -{
                    613: -      m_out(a,8,stdout);
                    614: -}
                    615: -fmout(a,f) mint *a; FILE *f;
                    616: -{     m_out(a,10,f);
                    617: -}
                    618: -fmin(a,f) mint *a; FILE *f;
                    619: -{
                    620: -      return(m_in(a,10,f));
                    621: -}
                    622: //GO.SYSIN DD mout.c
                    623: echo msqrt.c 1>&2
                    624: sed 's/.//' >msqrt.c <<'//GO.SYSIN DD msqrt.c'
                    625: -#include "mp.h"
                    626: -msqrt(a,b,r) mint *a,*b,*r;
                    627: -{     mint x,junk,y;
                    628: -      int j;
                    629: -      x.len=junk.len=y.len=0;
                    630: -      if(a->len<0) fatal("msqrt: neg arg");
                    631: -      if(a->len==0)
                    632: -      {       b->len=0;
                    633: -              r->len=0;
                    634: -              return(0);
                    635: -      }
                    636: -      if(a->len%2==1) x.len=(1+a->len)/2;
                    637: -      else x.len=1+a->len/2;
                    638: -      x.val=xalloc(x.len,"msqrt");
                    639: -      for(j=0;j<x.len;x.val[j++]=0);
                    640: -      if(a->len%2==1) x.val[x.len-1]=0400;
                    641: -      else x.val[x.len-1]=1;
                    642: -      xfree(b);
                    643: -      xfree(r);
                    644: -loop:
                    645: -      mdiv(a,&x,&y,&junk);
                    646: -      xfree(&junk);
                    647: -      madd(&x,&y,&y);
                    648: -      sdiv(&y,2,&y,(short *)&j);
                    649: -      if(mcmp(&x,&y)>0)
                    650: -      {       xfree(&x);
                    651: -              move(&y,&x);
                    652: -              xfree(&y);
                    653: -              goto loop;
                    654: -      }
                    655: -      xfree(&y);
                    656: -      move(&x,b);
                    657: -      mult(&x,&x,&x);
                    658: -      msub(a,&x,r);
                    659: -      xfree(&x);
                    660: -      return(r->len);
                    661: -}
                    662: -
                    663: -/* pathology: n<= 0 => r=rem=0, num <= 0, r=rem=0 */
                    664: -/* this is a lazy implementation, assuming n>=3 => root is a legal double */
                    665: -mroot(n, num, r, rem)
                    666: -mint *num, *r, *rem;
                    667: -{     extern double log(), exp();
                    668: -      double z;
                    669: -      int i;
                    670: -      static mint *xn, *xn1, *top, *bot;
                    671: -      static init;
                    672: -      if(!init++) {
                    673: -              xn = itom(0), xn1 = itom(0), top = itom(0), bot = itom(0);
                    674: -      }
                    675: -      if(n < 0 || num->len <= 0) {
                    676: -              msub(r, r, r);
                    677: -              move(r, rem);
                    678: -              return;
                    679: -      }
                    680: -      if(n == 1) {
                    681: -              move(num, r);
                    682: -              msub(rem, rem, rem);
                    683: -              return;
                    684: -      }
                    685: -      if(n == 2) {
                    686: -              msqrt(num, r, rem);
                    687: -              return;
                    688: -      }
                    689: -      /* compute approx bigger than root */
                    690: -      for(z = 0, i = 0; i < num->len; i++)
                    691: -              z = z/32768 + num->val[i];
                    692: -      /* num = z * 2^15*(len-1) */
                    693: -      z = exp((log(z) + 15*(num->len-1)*log(2.))/n);
                    694: -      z = 1.01 * z + 1;       /* make sure it is bigger than root */
                    695: -      dtom(z, r);
                    696: -      /* ((n-1)*x^n+num)/(n*x^(n-1))*/
                    697: -      for(;;) {
                    698: -              rpow(r, n - 1, xn1);
                    699: -              mult(r, xn1, xn);
                    700: -              imult(n-1, xn, top);
                    701: -              madd(top, num, top);
                    702: -              imult(n, xn1, bot);
                    703: -              mdiv(top, bot, xn1, rem);
                    704: -              switch(mcmp(xn1, r)) {
                    705: -              case -1:
                    706: -                      move(xn1, r);
                    707: -                      continue;
                    708: -              case 0:
                    709: -                      move(xn1, r);
                    710: -                      msub(num, xn, rem);
                    711: -                      return;
                    712: -              case 1: /* since r was too large to start with */
                    713: -                      msub(num, xn, rem);
                    714: -                      return;
                    715: -              }
                    716: -      }
                    717: -}
                    718: -
                    719: -static
                    720: -imult(n, a, b)
                    721: -mint *a, *b;
                    722: -{     mint *x;
                    723: -      x = itom(n);
                    724: -      mult(x, a, b);
                    725: -      msub(x, x,x);
                    726: -}
                    727: //GO.SYSIN DD msqrt.c
                    728: echo mult.c 1>&2
                    729: sed 's/.//' >mult.c <<'//GO.SYSIN DD mult.c'
                    730: -#include <mp.h>
                    731: -#undef unfast
                    732: -mult(a,b,c) mint *a,*b,*c;
                    733: -{     mint x,y,z;
                    734: -      int sign;
                    735: -      sign = 1;
                    736: -      x.val=a->val;
                    737: -      y.val=b->val;
                    738: -      z.len=0;
                    739: -      if(a->len<0)
                    740: -      {       x.len= -a->len;
                    741: -              sign= -sign;
                    742: -      }
                    743: -      else    x.len=a->len;
                    744: -      if(b->len<0)
                    745: -      {       y.len= -b->len;
                    746: -              sign= -sign;
                    747: -      }
                    748: -      else    y.len=b->len;
                    749: -      if(x.len == 0 || y.len == 0)
                    750: -              z.len = 0;
                    751: -      else if(x.len<y.len) m_mult(&y,&x,&z);
                    752: -      else m_mult(&x,&y,&z);
                    753: -      xfree(c);
                    754: -      if(sign<0) c->len= -z.len;
                    755: -      else c->len=z.len;
                    756: -      c->val=z.val;
                    757: -}
                    758: -#define S2 x=a->val[j];
                    759: -#define S3 x=x*b->val[i-j];
                    760: -#ifdef unfast
                    761: -#define S4 tradd(&carry,&sum,x);
                    762: -#else
                    763: -#define S4 sum.xx += x; if(sum.yy.high & 0100000) {sum.yy.high &= 077777; carry++;}
                    764: -#endif
                    765: -#define S5 c->val[i]=sum.yy.low&077777;
                    766: -#define S6 sum.xx=sum.xx>>15;
                    767: -#define S7 sum.yy.high=carry;
                    768: -m_mult(a,b,c)
                    769: -register mint *a,*b,*c;
                    770: -{     register long x;
                    771: -      union {long xx; struct half yy;} sum;
                    772: -      int carry;
                    773: -      int i,j;
                    774: -      c->val=xalloc(a->len+b->len,"m_mult");
                    775: -      sum.xx=0;
                    776: -      for(i=0;i<b->len;i++)
                    777: -      {       carry=0;
                    778: -              for(j=0;j<i+1;j++)
                    779: -              {       S2
                    780: -                      S3
                    781: -                      S4
                    782: -              }
                    783: -              S5
                    784: -              S6
                    785: -              S7
                    786: -      }
                    787: -      for(;i<a->len;i++)
                    788: -      {       carry=0;
                    789: -              for(j=i-b->len+1;j<i+1;j++)
                    790: -              {       S2
                    791: -                      S3
                    792: -                      S4
                    793: -              }
                    794: -              S5
                    795: -              S6
                    796: -              S7
                    797: -      }
                    798: -      for(;i<a->len+b->len;i++)
                    799: -      {       carry=0;
                    800: -              for(j=i-b->len+1;j<a->len;j++)
                    801: -              {       S2
                    802: -                      S3
                    803: -                      S4
                    804: -              }
                    805: -              S5
                    806: -              S6
                    807: -              S7
                    808: -      }
                    809: -      if(i == 0 || c->val[i-1]!=0)
                    810: -              c->len=a->len+b->len;
                    811: -      else    c->len=a->len+b->len-1;
                    812: -      return;
                    813: -}
                    814: -tradd(a,b,c)
                    815: -long c;
                    816: -int *a;
                    817: -register union {long xx; struct half yy;} *b;
                    818: -{
                    819: -      b->xx += c;
                    820: -      if(b->yy.high&0100000)
                    821: -      {       b->yy.high= b->yy.high&077777;
                    822: -              *a += 1;
                    823: -      }
                    824: -      return;
                    825: -}
                    826: //GO.SYSIN DD mult.c
                    827: echo pow.c 1>&2
                    828: sed 's/.//' >pow.c <<'//GO.SYSIN DD pow.c'
                    829: -#include "mp.h"
                    830: -static
                    831: -mpow(a,b,c,d) mint *a,*b,*c,*d;
                    832: -{     int i,j,n;
                    833: -      mint x,y;
                    834: -      x.len=y.len=0;
                    835: -      xfree(d);
                    836: -      d->len=1;
                    837: -      d->val=xalloc(1,"mpow");
                    838: -      *d->val=1;
                    839: -      for(j=0;j<b->len;j++)
                    840: -      {       n=b->val[b->len-j-1];
                    841: -              for(i=0;i<15;i++)
                    842: -              {       mult(d,d,&x);
                    843: -                      mdiv(&x,c,&y,d);
                    844: -                      if((n=n<<1)&0100000)
                    845: -                      {       mult(a,d,&x);
                    846: -                              mdiv(&x,c,&y,d);
                    847: -                      }
                    848: -              }
                    849: -      }
                    850: -      xfree(&x);
                    851: -      xfree(&y);
                    852: -      return;
                    853: -}
                    854: -rpow(a,n,b) mint *a,*b;
                    855: -{     mint x,y;
                    856: -      int i;
                    857: -      x.len=1;
                    858: -      x.val=xalloc(1,"rpow");
                    859: -      *x.val=n;
                    860: -      y.len=n*a->len+4;
                    861: -      y.val=xalloc(y.len,"rpow2");
                    862: -      for(i=0;i<y.len;i++) y.val[i]=0;
                    863: -      y.val[y.len-1]=010000;
                    864: -      xfree(b);
                    865: -      mpow(a,&x,&y,b);
                    866: -      xfree(&x);
                    867: -      xfree(&y);
                    868: -      return;
                    869: -}
                    870: //GO.SYSIN DD pow.c
                    871: echo util.c 1>&2
                    872: sed 's/.//' >util.c <<'//GO.SYSIN DD util.c'
                    873: -extern char *malloc();
                    874: -#include "stdio.h"
                    875: -#include "mp.h"
                    876: -move(a,b) mint *a,*b;
                    877: -{     int i,j;
                    878: -      if(a == b)
                    879: -              return;
                    880: -      xfree(b);
                    881: -      b->len=a->len;
                    882: -      if((i=a->len)<0)
                    883: -              i = -i;
                    884: -      if(i==0)
                    885: -              return;
                    886: -      b->val=xalloc(i,"move");
                    887: -      for(j=0;j<i;j++)
                    888: -              b->val[j]=a->val[j];
                    889: -      return;
                    890: -}
                    891: -dummy(){ }
                    892: -/*ARGSUSED*/
                    893: -short *xalloc(nint,s) char *s;
                    894: -{     short *i;
                    895: -      extern short *halloc();
                    896: -      i = halloc(nint);
                    897: -#ifdef DBG
                    898: -      i=(short *)malloc(2*(unsigned)nint+4);
                    899: -      if(dbg) fprintf(stderr, "%s: %o\n",s,i);
                    900: -#endif
                    901: -      if(i!=NULL) return(i);
                    902: -      fatal("mp: no free space");
                    903: -      return(0);
                    904: -}
                    905: -fatal(s) char *s;
                    906: -{
                    907: -      fprintf(stderr,"%s\n",s);
                    908: -      (void) fflush(stdout);
                    909: -      sleep(2);
                    910: -      abort();
                    911: -}
                    912: -xfree(c) mint *c;
                    913: -{
                    914: -#ifdef DBG
                    915: -      if(dbg) fprintf(stderr, "xfree ");
                    916: -#endif
                    917: -      if(c->len==0) return;
                    918: -      /*shfree(c->val);*/
                    919: -      hfree(c->val);
                    920: -      c->len=0;
                    921: -      return;
                    922: -}
                    923: -
                    924: -mfree(a)
                    925: -mint *a;
                    926: -{
                    927: -      xfree(a);
                    928: -      hfree(a);
                    929: -}
                    930: -mcan(a) mint *a;
                    931: -{     int i,j;
                    932: -      if((i=a->len)==0) return;
                    933: -      else if(i<0) i= -i;
                    934: -      for(j=i;j>0 && a->val[j-1]==0;j--);
                    935: -      if(j==i) return;
                    936: -      if(j==0) {      
                    937: -              xfree(a);
                    938: -              return;
                    939: -      }
                    940: -      if(a->len > 0) a->len=j;
                    941: -      else a->len = -j;
                    942: -}
                    943: -mint *itom(n)
                    944: -{     mint *a;
                    945: -      a=(mint *)xalloc(2,"itom");
                    946: -      if(n>0) {       
                    947: -              a->len=1;
                    948: -              a->val=xalloc(1,"itom1");
                    949: -              *a->val=n;
                    950: -              return(a);
                    951: -      }
                    952: -      else if(n<0) {  
                    953: -              a->len = -1;
                    954: -              a->val=xalloc(1,"itom2");
                    955: -              *a->val= -n;
                    956: -              return(a);
                    957: -      }
                    958: -      else {  
                    959: -              a->len=0;
                    960: -              return(a);
                    961: -      }
                    962: -}
                    963: -mcmp(a,b) mint *a,*b;
                    964: -{     mint c;
                    965: -      int res;
                    966: -      if(a->len < b->len)
                    967: -              return(-1);
                    968: -      if(a->len > b->len)
                    969: -              return(1);
                    970: -      c.len=0;
                    971: -      msub(a,b,&c);
                    972: -      res=c.len;
                    973: -      xfree(&c);
                    974: -      if(res < 0)
                    975: -              return(-1);
                    976: -      else if(res == 0)
                    977: -              return(0);
                    978: -      else
                    979: -              return(1);
                    980: -}
                    981: -
                    982: -dtom(z, r)
                    983: -double z;
                    984: -mint *r;
                    985: -{     int i, sgn;
                    986: -      static mint *c;
                    987: -      if(!c) {
                    988: -              c = itom(16384);
                    989: -              madd(c, c, c);
                    990: -      }
                    991: -      if(z < 0) {
                    992: -              sgn = 1;
                    993: -              z = -z;
                    994: -      }
                    995: -      else
                    996: -              sgn = 0;
                    997: -      for(i = 0; z >= 32768; i++)
                    998: -              z /= 32768;
                    999: -      move(c, r);
                   1000: -      r->len = 1;
                   1001: -      r->val[0] = z;
                   1002: -      while(--i >= 0) {
                   1003: -              z -= r->val[0];
                   1004: -              z *= 32768;
                   1005: -              mult(r, c, r);
                   1006: -              r->val[0] = z;
                   1007: -      }
                   1008: -      if(sgn)
                   1009: -              r->len = -r->len;
                   1010: -}
                   1011: //GO.SYSIN DD util.c
                   1012: echo Makefile 1>&2
                   1013: sed 's/.//' >Makefile <<'//GO.SYSIN DD Makefile'
                   1014: -DESTDIR=/usr/lib
                   1015: -CFLAGS=
                   1016: -OBJS= pow.o gcd.o msqrt.o mdiv.o mout.o mult.o madd.o util.o halloc.o 
                   1017: -
                   1018: -libmp.a: $(OBJS)
                   1019: -      ar cr libmp.a $(OBJS)
                   1020: -
                   1021: -install: libmp.a
                   1022: -      cp libmp.a ${DESTDIR}
                   1023: -      ranlib ${DESTDIR}/libmp.a
                   1024: -
                   1025: -clean:
                   1026: -      rm -f *.o libmp.a
                   1027: //GO.SYSIN DD Makefile

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.