|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.