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; }
int mpcmpfixfix(Mpint *a, Mpint *b) { Mpint c; mpmovefixfix(&c, a); mpsubfixfix(&c, b); return mptestfix(&c); }
void mpcomfix(Mpint *a) { Mpint b; mpmovecfix(&b, 1); mpnegfix(a); mpsubfixfix(a, &b); }
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; }