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

1.1     ! root        1: #include "mp.h"
        !             2: int mpdivdebug;
        !             3: mdiv(a,b,q,r) mint *a,*b,*q,*r;
        !             4: {      mint *x,*y, *z;
        !             5:        int alen, blen;
        !             6:        x = itom(0), y = itom(0);
        !             7:        z = itom(0);
        !             8:        move(a, x);
        !             9:        move(b, y);
        !            10:        alen = x->len;
        !            11:        if(x->len<0) {x->len= -x->len;}
        !            12:        blen = y->len;
        !            13:        if(y->len<0) {y->len= -y->len;}
        !            14:        xfree(q);
        !            15:        xfree(r);
        !            16:        m_div(x,y,q,r);
        !            17:        if(mpdivdebug) {
        !            18:                mult(y, q, z);
        !            19:                madd(z, r, z);
        !            20:                if(mcmp(z, x) != 0) {
        !            21:                        mout(a);
        !            22:                        mout(b);
        !            23:                        fatal("mdiv err");
        !            24:                }
        !            25:        }
        !            26:        if(alen < 0) {
        !            27:                mint o;
        !            28:                short i = 1;
        !            29:                o.len = 1;
        !            30:                o.val = &i;
        !            31:                if(r->len == 0) {
        !            32:                        if(blen > 0)
        !            33:                                q->len = -q->len;
        !            34:                        goto out;
        !            35:                }
        !            36:                msub(r, y, r);
        !            37:                r->len = -r->len;
        !            38:                madd(q, &o, q);
        !            39:                if(blen > 0)
        !            40:                        q->len = -q->len;
        !            41:                goto out;
        !            42:        }
        !            43:        if(blen < 0)
        !            44:                q->len = -q->len;
        !            45: out:
        !            46:        mfree(z);
        !            47:        mfree(y);
        !            48:        mfree(x);
        !            49: }
        !            50: #ifdef vax
        !            51: union zz {
        !            52:        long a;
        !            53:        struct {
        !            54:                unsigned int lo:15, hi:15;
        !            55:        } b;
        !            56: };
        !            57: #else
        !            58: union zz {
        !            59:        long a;
        !            60:        struct {
        !            61:                unsigned int :2, hi:15,lo:15;
        !            62:        } b;
        !            63: };
        !            64: #endif
        !            65: m_dsb(q,n,a,b) short *a,*b;
        !            66: {      long int qx, u;
        !            67:        union zz x;
        !            68:        int borrow,j;
        !            69:        qx=q;
        !            70:        x.a = 0;
        !            71:        for(j = 0; j < n; j++) {
        !            72:                x.a = qx * a[j] + x.b.hi;
        !            73:                if((b[j] -= x.b.lo) < 0) {
        !            74:                        b[j] += (1 << 15);
        !            75:                        x.b.hi += 1;
        !            76:                }
        !            77:        }
        !            78:        if((b[j] -= x.b.hi) >= 0)
        !            79:                return(0);
        !            80:        borrow=0;
        !            81:        for(j=0;j<n;j++)
        !            82:        {       u=a[j]+b[j]+borrow;
        !            83:                if(u & 0100000)
        !            84:                        borrow = 1;
        !            85:                else borrow=0;
        !            86:                b[j]=u&077777;
        !            87:        }
        !            88:        { return(1);}
        !            89: }
        !            90: m_trq(v1,v2,u1,u2,u3)
        !            91: {      long int d;
        !            92:        long int x1;
        !            93:        if(u1==v1) d=077777;
        !            94:        else d=(u1*0100000L+u2)/v1;
        !            95:        while(1)
        !            96:        {       x1=u1*0100000L+u2-v1*d;
        !            97:                x1=x1*0100000L+u3-v2*d;
        !            98:                if(x1<0) d=d-1;
        !            99:                else {return(d);}
        !           100:        }
        !           101: }
        !           102: m_div(a,b,q,r) mint *a,*b,*q,*r;
        !           103: {      mint u,v,x,w;
        !           104:        short d,*qval;
        !           105:        int qq,n,v1,v2,j;
        !           106:        u.len=v.len=x.len=w.len=0;
        !           107:        if(b->len==0) { fatal("mdiv divide by zero"); return;}
        !           108:        if(b->len==1)
        !           109:        {       r->val=xalloc(1,"m_div1");
        !           110:                sdiv(a,b->val[0],q,r->val);
        !           111:                if(r->val[0]==0)
        !           112:                {       shfree(r->val);
        !           113:                        r->len=0;
        !           114:                }
        !           115:                else r->len=1;
        !           116:                return;
        !           117:        }
        !           118:        if(a->len < b->len)
        !           119:        {       q->len=0;
        !           120:                r->len=a->len;
        !           121:                r->val=xalloc(r->len,"m_div2");
        !           122:                for(qq=0;qq<r->len;qq++) r->val[qq]=a->val[qq];
        !           123:                return;
        !           124:        }
        !           125:        x.len=1;
        !           126:        x.val = &d;
        !           127:        n=b->len;
        !           128:        d=0100000L/(b->val[n-1]+1L);
        !           129:        mult(a,&x,&u); /*subtle: relies on fact that mult allocates extra space */
        !           130:        mult(b,&x,&v);
        !           131:        v1=v.val[n-1];
        !           132:        v2=v.val[n-2];
        !           133:        qval=xalloc(a->len-n+1,"m_div3");
        !           134:        for(j=a->len-n;j>=0;j--)
        !           135:        {       qq=m_trq(v1,v2,u.val[j+n],u.val[j+n-1],u.val[j+n-2]);
        !           136:                if(m_dsb(qq,n,v.val,&(u.val[j]))) qq -= 1;
        !           137:                qval[j]=qq;
        !           138:        }
        !           139:        x.len=n;
        !           140:        x.val=u.val;
        !           141:        mcan(&x);
        !           142:        sdiv(&x,d,&w,(short *)&qq);
        !           143:        r->len=w.len;
        !           144:        r->val=w.val;
        !           145:        q->val=qval;
        !           146:        qq=a->len-n+1;
        !           147:        if(qq>0 && qval[qq-1]==0) qq -= 1;
        !           148:        q->len=qq;
        !           149:        if(qq==0) shfree(qval);
        !           150:        if(x.len!=0) xfree(&u);
        !           151:        xfree(&v);
        !           152:        return;
        !           153: }

unix.superglobalmegacorp.com

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