Пример #1
0
void
mpdivfract(Mpint *a, Mpint *b)
{
	Mpint n, d;
	int i, j, neg;
	long *a1, x;

	mpmovefixfix(&n, a);	// numerator
	mpmovefixfix(&d, b);	// denominator
	a1 = &a->a[Mpprec];	// quotient

	neg = n.neg ^ d.neg;
	n.neg = 0;
	d.neg = 0;

	for(i=0; i<Mpprec; i++) {
		x = 0;
		for(j=0; j<Mpscale; j++) {
			x <<= 1;
			if(mpcmp(&d, &n) <= 0) {
				x |= 1;
				mpsubfixfix(&n, &d);
			}
			mprsh(&d);
		}
		*--a1 = x;
	}
	a->neg = neg;
}
Пример #2
0
int
Bconv(Fmt *fp)
{
	char buf[500], *p;
	Mpint *xval, q, r, ten;
	int f;

	xval = va_arg(fp->args, Mpint*);
	mpmovefixfix(&q, xval);
	f = 0;
	if(mptestfix(&q) < 0) {
		f = 1;
		mpnegfix(&q);
	}
	mpmovecfix(&ten, 10);

	p = &buf[sizeof(buf)];
	*--p = 0;
	for(;;) {
		mpdivmodfixfix(&q, &r, &q, &ten);
		*--p = mpgetfix(&r) + '0';
		if(mptestfix(&q) <= 0)
			break;
	}
	if(f)
		*--p = '-';
	return fmtstrcpy(fp, p);
}
Пример #3
0
void
mpmodfixfix(Mpint *a, Mpint *b)
{
	Mpint q, r;

	mpdivmodfixfix(&q, &r, a, b);
	mpmovefixfix(a, &r);
}
Пример #4
0
int
mpcmpfixfix(Mpint *a, Mpint *b)
{
	Mpint c;

	mpmovefixfix(&c, a);
	mpsubfixfix(&c, b);
	return mptestfix(&c);
}
Пример #5
0
void
mpmulfixfix(Mpint *a, Mpint *b)
{

	int i, j, na, nb;
	long *a1, x;
	Mpint s, q;

	if(a->ovf || b->ovf) {
		yyerror("ovf in mpmulfixfix");
		a->ovf = 1;
		return;
	}

	// pick the smaller
	// to test for bits
	na = mplen(a);
	nb = mplen(b);
	if(na > nb) {
		mpmovefixfix(&s, a);
		a1 = &b->a[0];
		na = nb;
	} else {
		mpmovefixfix(&s, b);
		a1 = &a->a[0];
	}
	s.neg = 0;

	mpmovecfix(&q, 0);
	for(i=0; i<na; i++) {
		x = *a1++;
		for(j=0; j<Mpscale; j++) {
			if(x & 1)
				mpaddfixfix(&q, &s);
			mplsh(&s);
			x >>= 1;
		}
	}

	q.neg = a->neg ^ b->neg;
	mpmovefixfix(a, &q);
	if(a->ovf)
		yyerror("set ovf in mpmulfixfix");
}
Пример #6
0
void
mpmulfract(Mpint *a, Mpint *b)
{

	int i, j;
	long *a1, x;
	Mpint s, q;

	if(a->ovf || b->ovf) {
		yyerror("ovf in mpmulflt");
		a->ovf = 1;
		return;
	}

	mpmovefixfix(&s, b);
	a1 = &a->a[Mpprec];
	s.neg = 0;
	mpmovecfix(&q, 0);

	for(i=0; i<Mpprec; i++) {
		x = *--a1;
		if(x == 0) {
			mprshw(&s);
			continue;
		}
		for(j=0; j<Mpscale; j++) {
			x <<= 1;
			if(x & Mpbase)
				mpaddfixfix(&q, &s);
			mprsh(&s);
		}
	}

	q.neg = a->neg ^ b->neg;
	mpmovefixfix(a, &q);
	if(a->ovf)
		yyerror("set ovf in mpmulflt");
}
Пример #7
0
void
mpdivmodfixfix(Mpint *q, Mpint *r, Mpint *n, Mpint *d)
{
	int i, ns, ds;

	ns = n->neg;
	ds = d->neg;
	n->neg = 0;
	d->neg = 0;

	mpmovefixfix(r, n);
	mpmovecfix(q, 0);

	// shift denominator until it
	// is larger than numerator
	for(i=0; i<Mpprec*Mpscale; i++) {
		if(mpcmp(d, r) > 0)
			break;
		mplsh(d);
	}

	// if it never happens
	// denominator is probably zero
	if(i >= Mpprec*Mpscale) {
		q->ovf = 1;
		r->ovf = 1;
		n->neg = ns;
		d->neg = ds;
		yyerror("set ovf in mpdivmodfixfix");
		return;
	}

	// shift denominator back creating
	// quotient a bit at a time
	// when done the remaining numerator
	// will be the remainder
	for(; i>0; i--) {
		mplsh(q);
		mprsh(d);
		if(mpcmp(d, r) <= 0) {
			mpaddcfix(q, 1);
			mpsubfixfix(r, d);
		}
	}

	n->neg = ns;
	d->neg = ds;
	r->neg = ns;
	q->neg = ns^ds;
}
Пример #8
0
int
Bconv(Fmt *fp)
{
	char buf[500], *p;
	Mpint *xval, q, r, ten, sixteen;
	int f, digit;

	xval = va_arg(fp->args, Mpint*);
	mpmovefixfix(&q, xval);
	f = 0;
	if(mptestfix(&q) < 0) {
		f = 1;
		mpnegfix(&q);
	}

	p = &buf[sizeof(buf)];
	*--p = 0;
	if(fp->flags & FmtSharp) {
		// Hexadecimal
		mpmovecfix(&sixteen, 16);
		for(;;) {
			mpdivmodfixfix(&q, &r, &q, &sixteen);
			digit = mpgetfix(&r);
			if(digit < 10)
				*--p = digit + '0';
			else
				*--p = digit - 10 + 'A';
			if(mptestfix(&q) <= 0)
				break;
		}
		*--p = 'x';
		*--p = '0';
	} else {
		// Decimal
		mpmovecfix(&ten, 10);
		for(;;) {
			mpdivmodfixfix(&q, &r, &q, &ten);
			*--p = mpgetfix(&r) + '0';
			if(mptestfix(&q) <= 0)
				break;
		}
	}
	if(f)
		*--p = '-';
	return fmtstrcpy(fp, p);
}