1: /* @(#)mdiv.c 4.1 12/25/82 */ 2: 3: #include <mp.h> 4: mdiv(a,b,q,r) MINT *a,*b,*q,*r; 5: { MINT x,y; 6: int sign; 7: sign=1; 8: x.val=a->val; 9: y.val=b->val; 10: x.len=a->len; 11: if(x.len<0) {sign= -1; x.len= -x.len;} 12: y.len=b->len; 13: if(y.len<0) {sign= -sign; y.len= -y.len;} 14: xfree(q); 15: xfree(r); 16: m_div(&x,&y,q,r); 17: if(sign==-1) 18: { q->len= -q->len; 19: r->len = - r->len; 20: } 21: return; 22: } 23: m_dsb(q,n,a,b) short *a,*b; 24: { long int x,qx; 25: int borrow,j,u; 26: qx=q; 27: borrow=0; 28: for(j=0;j<n;j++) 29: { x=borrow-a[j]*qx+b[j]; 30: b[j]=x&077777; 31: borrow=x>>15; 32: } 33: x=borrow+b[j]; 34: b[j]=x&077777; 35: if(x>>15 ==0) { return(0);} 36: borrow=0; 37: for(j=0;j<n;j++) 38: { u=a[j]+b[j]+borrow; 39: if(u<0) borrow=1; 40: else borrow=0; 41: b[j]=u&077777; 42: } 43: { return(1);} 44: } 45: m_trq(v1,v2,u1,u2,u3) 46: { long int d; 47: long int x1; 48: if(u1==v1) d=077777; 49: else d=(u1*0100000L+u2)/v1; 50: while(1) 51: { x1=u1*0100000L+u2-v1*d; 52: x1=x1*0100000L+u3-v2*d; 53: if(x1<0) d=d-1; 54: else {return(d);} 55: } 56: } 57: m_div(a,b,q,r) MINT *a,*b,*q,*r; 58: { MINT u,v,x,w; 59: short d,*qval; 60: int qq,n,v1,v2,j; 61: u.len=v.len=x.len=w.len=0; 62: if(b->len==0) { fatal("mdiv divide by zero"); return;} 63: if(b->len==1) 64: { r->val=xalloc(1,"m_div1"); 65: sdiv(a,b->val[0],q,r->val); 66: if(r->val[0]==0) 67: { shfree(r->val); 68: r->len=0; 69: } 70: else r->len=1; 71: return; 72: } 73: if(a->len < b->len) 74: { q->len=0; 75: r->len=a->len; 76: r->val=xalloc(r->len,"m_div2"); 77: for(qq=0;qq<r->len;qq++) r->val[qq]=a->val[qq]; 78: return; 79: } 80: x.len=1; 81: x.val = &d; 82: n=b->len; 83: d=0100000L/(b->val[n-1]+1L); 84: mult(a,&x,&u); /*subtle: relies on fact that mult allocates extra space */ 85: mult(b,&x,&v); 86: v1=v.val[n-1]; 87: v2=v.val[n-2]; 88: qval=xalloc(a->len-n+1,"m_div3"); 89: for(j=a->len-n;j>=0;j--) 90: { qq=m_trq(v1,v2,u.val[j+n],u.val[j+n-1],u.val[j+n-2]); 91: if(m_dsb(qq,n,v.val,&(u.val[j]))) qq -= 1; 92: qval[j]=qq; 93: } 94: x.len=n; 95: x.val=u.val; 96: mcan(&x); 97: sdiv(&x,d,&w,(short *)&qq); 98: r->len=w.len; 99: r->val=w.val; 100: q->val=qval; 101: qq=a->len-n+1; 102: if(qq>0 && qval[qq-1]==0) qq -= 1; 103: q->len=qq; 104: if(qq==0) shfree(qval); 105: if(x.len!=0) xfree(&u); 106: xfree(&v); 107: return; 108: }