Annotation of researchv10no/libmp/msqrt.c, revision 1.1

1.1     ! root        1: #include "mp.h"
        !             2: msqrt(a,b,r) mint *a,*b,*r;
        !             3: {      mint x,junk,y;
        !             4:        int j;
        !             5:        x.len=junk.len=y.len=0;
        !             6:        if(a->len<0) fatal("msqrt: neg arg");
        !             7:        if(a->len==0)
        !             8:        {       b->len=0;
        !             9:                r->len=0;
        !            10:                return(0);
        !            11:        }
        !            12:        if(a->len%2==1) x.len=(1+a->len)/2;
        !            13:        else x.len=1+a->len/2;
        !            14:        x.val=xalloc(x.len,"msqrt");
        !            15:        for(j=0;j<x.len;x.val[j++]=0);
        !            16:        if(a->len%2==1) x.val[x.len-1]=0400;
        !            17:        else x.val[x.len-1]=1;
        !            18:        xfree(b);
        !            19:        xfree(r);
        !            20: loop:
        !            21:        mdiv(a,&x,&y,&junk);
        !            22:        xfree(&junk);
        !            23:        madd(&x,&y,&y);
        !            24:        sdiv(&y,2,&y,(short *)&j);
        !            25:        if(mcmp(&x,&y)>0)
        !            26:        {       xfree(&x);
        !            27:                move(&y,&x);
        !            28:                xfree(&y);
        !            29:                goto loop;
        !            30:        }
        !            31:        xfree(&y);
        !            32:        move(&x,b);
        !            33:        mult(&x,&x,&x);
        !            34:        msub(a,&x,r);
        !            35:        xfree(&x);
        !            36:        return(r->len);
        !            37: }
        !            38: 
        !            39: /* pathology: n<= 0 => r=rem=0, num <= 0, r=rem=0 */
        !            40: /* this is a lazy implementation, assuming n>=3 => root is a legal double */
        !            41: mroot(n, num, r, rem)
        !            42: mint *num, *r, *rem;
        !            43: {      extern double log(), exp();
        !            44:        double z;
        !            45:        int i;
        !            46:        static mint *xn, *xn1, *top, *bot;
        !            47:        static init;
        !            48:        if(!init++) {
        !            49:                xn = itom(0), xn1 = itom(0), top = itom(0), bot = itom(0);
        !            50:        }
        !            51:        if(n < 0 || num->len <= 0) {
        !            52:                msub(r, r, r);
        !            53:                move(r, rem);
        !            54:                return;
        !            55:        }
        !            56:        if(n == 1) {
        !            57:                move(num, r);
        !            58:                msub(rem, rem, rem);
        !            59:                return;
        !            60:        }
        !            61:        if(n == 2) {
        !            62:                msqrt(num, r, rem);
        !            63:                return;
        !            64:        }
        !            65:        /* compute approx bigger than root */
        !            66:        for(z = 0, i = 0; i < num->len; i++)
        !            67:                z = z/32768 + num->val[i];
        !            68:        /* num = z * 2^15*(len-1) */
        !            69:        z = exp((log(z) + 15*(num->len-1)*log(2.))/n);
        !            70:        z = 1.01 * z + 1;       /* make sure it is bigger than root */
        !            71:        dtom(z, r);
        !            72:        /* ((n-1)*x^n+num)/(n*x^(n-1))*/
        !            73:        for(;;) {
        !            74:                rpow(r, n - 1, xn1);
        !            75:                mult(r, xn1, xn);
        !            76:                imult(n-1, xn, top);
        !            77:                madd(top, num, top);
        !            78:                imult(n, xn1, bot);
        !            79:                mdiv(top, bot, xn1, rem);
        !            80:                switch(mcmp(xn1, r)) {
        !            81:                case -1:
        !            82:                        move(xn1, r);
        !            83:                        continue;
        !            84:                case 0:
        !            85:                        move(xn1, r);
        !            86:                        msub(num, xn, rem);
        !            87:                        return;
        !            88:                case 1: /* since r was too large to start with */
        !            89:                        msub(num, xn, rem);
        !            90:                        return;
        !            91:                }
        !            92:        }
        !            93: }
        !            94: 
        !            95: static
        !            96: imult(n, a, b)
        !            97: mint *a, *b;
        !            98: {      mint *x;
        !            99:        x = itom(n);
        !           100:        mult(x, a, b);
        !           101:        msub(x, x,x);
        !           102: }

unix.superglobalmegacorp.com

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