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 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); }
void mpmodfixfix(Mpint *a, Mpint *b) { Mpint q, r; mpdivmodfixfix(&q, &r, a, b); mpmovefixfix(a, &r); }
int mpcmpfixfix(Mpint *a, Mpint *b) { Mpint c; mpmovefixfix(&c, a); mpsubfixfix(&c, b); return mptestfix(&c); }
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"); }
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"); }
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; }
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); }