Blk* mult(Blk *p, Blk *q) { Blk *mp, *mq, *mr; int sign, offset, carry; int cq, cp, mt, mcr; offset = sign = 0; fsfile(p); mp = p; if(sfbeg(p) == 0) { if(sbackc(p)<0) { mp = copy(p,length(p)); chsign(mp); sign = ~sign; } } fsfile(q); mq = q; if(sfbeg(q) == 0){ if(sbackc(q)<0) { mq = copy(q,length(q)); chsign(mq); sign = ~sign; } } mr = salloc(length(mp)+length(mq)); zero(mr); rewind(mq); while(sfeof(mq) == 0) { cq = sgetc(mq); rewind(mp); rewind(mr); mr->rd += offset; carry=0; while(sfeof(mp) == 0) { cp = sgetc(mp); mcr = sfeof(mr)?0:slookc(mr); mt = cp*cq + carry + mcr; carry = mt/100; salterc(mr,mt%100); } offset++; if(carry != 0) { mcr = sfeof(mr)?0:slookc(mr); salterc(mr,mcr+carry); } } if(sign < 0) { chsign(mr); } if(mp != p) release(mp); if(mq != q) release(mq); return(mr); }
Blk* dcsqrt(Blk *p) { Blk *t, *r, *q, *s; int c, n, nn; n = length(p); fsfile(p); c = sbackc(p); if((n&1) != 1) c = c*100+(sfbeg(p)?0:sbackc(p)); n = (n+1)>>1; r = salloc(n); zero(r); seekc(r,n); nn=1; while((c -= nn)>=0) nn+=2; c=(nn+1)>>1; fsfile(r); backc(r); if(c>=100) { c -= 100; salterc(r,c); sputc(r,1); } else salterc(r,c); for(;;){ q = div(p,r); s = add(q,r); release(q); release(rem); q = div(s,sqtemp); release(s); release(rem); s = copy(r,length(r)); chsign(s); t = add(s,q); release(s); fsfile(t); nn = sfbeg(t)?0:sbackc(t); if(nn>=0) break; release(r); release(t); r = q; } release(t); release(q); release(p); return(r); }
Blk* add(Blk *a1, Blk *a2) { Blk *p; int carry, n, size, c, n1, n2; size = length(a1)>length(a2)?length(a1):length(a2); p = salloc(size); rewind(a1); rewind(a2); carry=0; while(--size >= 0) { n1 = sfeof(a1)?0:sgetc(a1); n2 = sfeof(a2)?0:sgetc(a2); n = n1 + n2 + carry; if(n>=100) { carry=1; n -= 100; } else if(n<0) { carry = -1; n += 100; } else carry = 0; sputc(p,n); } if(carry != 0) sputc(p,carry); fsfile(p); if(sfbeg(p) == 0) { c = 0; while(sfbeg(p) == 0 && (c = sbackc(p)) == 0) ; if(c != 0) salterc(p,c); truncate(p); } fsfile(p); if(sfbeg(p) == 0 && sbackc(p) == -1) { while((c = sbackc(p)) == 99) { if(c == -1) break; } skipc(p); salterc(p,-1); truncate(p); } return(p); }
void chsign(Blk *p) { int carry; char ct; carry=0; rewind(p); while(sfeof(p) == 0) { ct=100-slookc(p)-carry; carry=1; if(ct>=100) { ct -= 100; carry=0; } salterc(p,ct); } if(carry != 0) { sputc(p,-1); fsfile(p); backc(p); ct = sbackc(p); if(ct == 99 /*&& !sfbeg(p)*/) { truncate(p); sputc(p,-1); } } else{ fsfile(p); ct = sbackc(p); if(ct == 0) truncate(p); } return; }
void chsign(struct blk *p) { register int carry; register char ct; carry=0; rewind(p); while(sfeof(p) == 0){ ct=100-slookc(p)-carry; carry=1; if(ct>=100){ ct -= 100; carry=0; } salterc(p,ct); } if(carry != 0){ sputc(p,-1); fsfile(p); sbackc(p); ct = sbackc(p); if(ct == 99){ truncate(p); sputc(p,-1); } } else{ fsfile(p); ct = sbackc(p); if(ct == 0)truncate(p); } return; }
Blk* div(Blk *ddivd, Blk *ddivr) { int divsign, remsign, offset, divcarry, carry, dig, magic, d, dd, under, first; long c, td, cc; Blk *ps, *px, *p, *divd, *divr; dig = 0; under = 0; divcarry = 0; rem = 0; p = salloc(0); if(length(ddivr) == 0) { pushp(ddivr); Bprint(&bout,"divide by 0\n"); return(p); } divsign = remsign = first = 0; divr = ddivr; fsfile(divr); if(sbackc(divr) == -1) { divr = copy(ddivr,length(ddivr)); chsign(divr); divsign = ~divsign; } divd = copy(ddivd,length(ddivd)); fsfile(divd); if(sfbeg(divd) == 0 && sbackc(divd) == -1) { chsign(divd); divsign = ~divsign; remsign = ~remsign; } offset = length(divd) - length(divr); if(offset < 0) goto ddone; seekc(p,offset+1); sputc(divd,0); magic = 0; fsfile(divr); c = sbackc(divr); if(c < 10) magic++; c = c * 100 + (sfbeg(divr)?0:sbackc(divr)); if(magic>0){ c = (c * 100 +(sfbeg(divr)?0:sbackc(divr)))*2; c /= 25; } while(offset >= 0) { first++; fsfile(divd); td = sbackc(divd) * 100; dd = sfbeg(divd)?0:sbackc(divd); td = (td + dd) * 100; dd = sfbeg(divd)?0:sbackc(divd); td = td + dd; cc = c; if(offset == 0) td++; else cc++; if(magic != 0) td = td<<3; dig = td/cc; under=0; if(td%cc < 8 && dig > 0 && magic) { dig--; under=1; } rewind(divr); rewind(divxyz); carry = 0; while(sfeof(divr) == 0) { d = sgetc(divr)*dig+carry; carry = d / 100; salterc(divxyz,d%100); } salterc(divxyz,carry); rewind(divxyz); seekc(divd,offset); carry = 0; while(sfeof(divd) == 0) { d = slookc(divd); d = d-(sfeof(divxyz)?0:sgetc(divxyz))-carry; carry = 0; if(d < 0) { d += 100; carry = 1; } salterc(divd,d); } divcarry = carry; backc(p); salterc(p,dig); backc(p); fsfile(divd); d=sbackc(divd); if((d != 0) && /*!divcarry*/ (offset != 0)) { d = sbackc(divd) + 100; salterc(divd,d); } if(--offset >= 0) divd->wt--; } if(under) { /* undershot last - adjust*/ px = copy(divr,length(divr)); /*11/88 don't corrupt ddivr*/ chsign(px); ps = add(px,divd); fsfile(ps); if(length(ps) > 0 && sbackc(ps) < 0) { release(ps); /*only adjust in really undershot*/ } else { release(divd); salterc(p, dig+1); divd=ps; } } if(divcarry != 0) { salterc(p,dig-1); salterc(divd,-1); ps = add(divr,divd); release(divd); divd = ps; } rewind(p); divcarry = 0; while(sfeof(p) == 0){ d = slookc(p)+divcarry; divcarry = 0; if(d >= 100){ d -= 100; divcarry = 1; } salterc(p,d); } if(divcarry != 0)salterc(p,divcarry); fsfile(p); while(sfbeg(p) == 0) { if(sbackc(p) != 0) break; truncate(p); } if(divsign < 0) chsign(p); fsfile(divd); while(sfbeg(divd) == 0) { if(sbackc(divd) != 0) break; truncate(divd); } ddone: if(remsign<0) chsign(divd); if(divr != ddivr) release(divr); rem = divd; return(p); }
struct blk * div(struct blk *ddivd,struct blk *ddivr) { int divsign,remsign,offset,divcarry = 0; int carry, dig = 0,magic,d = 0,dd; long c,td,cc; struct blk *ps; register struct blk *p,*divd,*divr; rem = 0; p = salloc(0); if(length(ddivr) == 0){ pushp(ddivr); printf("divide by 0\n"); return NULL; } divsign = remsign = 0; divr = ddivr; fsfile(divr); if(sbackc(divr) == -1){ divr = copy(ddivr,length(ddivr)); chsign(divr); divsign = ~divsign; } divd = copy(ddivd,length(ddivd)); fsfile(divd); if(sfbeg(divd) == 0 && sbackc(divd) == -1){ chsign(divd); divsign = ~divsign; remsign = ~remsign; } offset = length(divd) - length(divr); if(offset < 0)goto ddone; seekc(p,offset+1); sputc(divd,0); magic = 0; fsfile(divr); c = sbackc(divr); if(c<10)magic++; c = c*100 + (sfbeg(divr)?0:sbackc(divr)); if(magic>0){ c = (c*100 +(sfbeg(divr)?0:sbackc(divr)))*2; c /= 25; } while(offset >= 0){ fsfile(divd); td = sbackc(divd)*100; dd = sfbeg(divd)?0:sbackc(divd); td = (td+dd)*100; dd = sfbeg(divd)?0:sbackc(divd); td = td+dd; cc = c; if(offset == 0)td += 1; else cc += 1; if(magic != 0)td = td<<3; dig = td/cc; rewind(divr); rewind(divxyz); carry = 0; while(sfeof(divr) == 0){ d = sgetc(divr)*dig+carry; carry = d / 100; salterc(divxyz,d%100); } salterc(divxyz,carry); rewind(divxyz); seekc(divd,offset); carry = 0; while(sfeof(divd) == 0){ d = slookc(divd); d = d-(sfeof(divxyz)?0:sgetc(divxyz))-carry; carry = 0; if(d < 0){ d += 100; carry = 1; } salterc(divd,d); } divcarry = carry; sbackc(p); salterc(p,dig); sbackc(p); if(--offset >= 0){ if(d > 0){ sbackc(divd); dd=sbackc(divd); salterc(divd,dd+100); } divd->wt--; } } if(divcarry != 0){ salterc(p,dig-1); salterc(divd,-1); ps = add(divr,divd); release(divd); divd = ps; } rewind(p); divcarry = 0; while(sfeof(p) == 0){ d = slookc(p)+divcarry; divcarry = 0; if(d >= 100){ d -= 100; divcarry = 1; } salterc(p,d); } if(divcarry != 0)salterc(p,divcarry); fsfile(p); while(sfbeg(p) == 0){ if(sbackc(p) == 0)truncate(p); else break; } if(divsign < 0)chsign(p); fsfile(divd); while(sfbeg(divd) == 0){ if(sbackc(divd) == 0)truncate(divd); else break; } ddone: if(remsign<0)chsign(divd); if(divr != ddivr)release(divr); rem = divd; return(p); }