|
|
researchv10 Norman
#include "mp.h"
int mpdivdebug;
mdiv(a,b,q,r) mint *a,*b,*q,*r;
{ mint *x,*y, *z;
int alen, blen;
x = itom(0), y = itom(0);
z = itom(0);
move(a, x);
move(b, y);
alen = x->len;
if(x->len<0) {x->len= -x->len;}
blen = y->len;
if(y->len<0) {y->len= -y->len;}
xfree(q);
xfree(r);
m_div(x,y,q,r);
if(mpdivdebug) {
mult(y, q, z);
madd(z, r, z);
if(mcmp(z, x) != 0) {
mout(a);
mout(b);
fatal("mdiv err");
}
}
if(alen < 0) {
mint o;
short i = 1;
o.len = 1;
o.val = &i;
if(r->len == 0) {
if(blen > 0)
q->len = -q->len;
goto out;
}
msub(r, y, r);
r->len = -r->len;
madd(q, &o, q);
if(blen > 0)
q->len = -q->len;
goto out;
}
if(blen < 0)
q->len = -q->len;
out:
mfree(z);
mfree(y);
mfree(x);
}
#ifdef vax
union zz {
long a;
struct {
unsigned int lo:15, hi:15;
} b;
};
#else
union zz {
long a;
struct {
unsigned int :2, hi:15,lo:15;
} b;
};
#endif
m_dsb(q,n,a,b) short *a,*b;
{ long int qx, u;
union zz x;
int borrow,j;
qx=q;
x.a = 0;
for(j = 0; j < n; j++) {
x.a = qx * a[j] + x.b.hi;
if((b[j] -= x.b.lo) < 0) {
b[j] += (1 << 15);
x.b.hi += 1;
}
}
if((b[j] -= x.b.hi) >= 0)
return(0);
borrow=0;
for(j=0;j<n;j++)
{ u=a[j]+b[j]+borrow;
if(u & 0100000)
borrow = 1;
else borrow=0;
b[j]=u&077777;
}
{ return(1);}
}
m_trq(v1,v2,u1,u2,u3)
{ long int d;
long int x1;
if(u1==v1) d=077777;
else d=(u1*0100000L+u2)/v1;
while(1)
{ x1=u1*0100000L+u2-v1*d;
x1=x1*0100000L+u3-v2*d;
if(x1<0) d=d-1;
else {return(d);}
}
}
m_div(a,b,q,r) mint *a,*b,*q,*r;
{ mint u,v,x,w;
short d,*qval;
int qq,n,v1,v2,j;
u.len=v.len=x.len=w.len=0;
if(b->len==0) { fatal("mdiv divide by zero"); return;}
if(b->len==1)
{ r->val=xalloc(1,"m_div1");
sdiv(a,b->val[0],q,r->val);
if(r->val[0]==0)
{ shfree(r->val);
r->len=0;
}
else r->len=1;
return;
}
if(a->len < b->len)
{ q->len=0;
r->len=a->len;
r->val=xalloc(r->len,"m_div2");
for(qq=0;qq<r->len;qq++) r->val[qq]=a->val[qq];
return;
}
x.len=1;
x.val = &d;
n=b->len;
d=0100000L/(b->val[n-1]+1L);
mult(a,&x,&u); /*subtle: relies on fact that mult allocates extra space */
mult(b,&x,&v);
v1=v.val[n-1];
v2=v.val[n-2];
qval=xalloc(a->len-n+1,"m_div3");
for(j=a->len-n;j>=0;j--)
{ qq=m_trq(v1,v2,u.val[j+n],u.val[j+n-1],u.val[j+n-2]);
if(m_dsb(qq,n,v.val,&(u.val[j]))) qq -= 1;
qval[j]=qq;
}
x.len=n;
x.val=u.val;
mcan(&x);
sdiv(&x,d,&w,(short *)&qq);
r->len=w.len;
r->val=w.val;
q->val=qval;
qq=a->len-n+1;
if(qq>0 && qval[qq-1]==0) qq -= 1;
q->len=qq;
if(qq==0) shfree(qval);
if(x.len!=0) xfree(&u);
xfree(&v);
return;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.