Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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);
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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);
}
Пример #7
0
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);
}