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