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; }
// // right shift mpint by Mpscale // ignores sign and overflow // static void mprshw(Mpint *a) { long *a1, lo; int i; lo = a->a[0]; a1 = &a->a[0]; for(i=1; i<Mpprec; i++) { a1[0] = a1[1]; a1++; } a1[0] = 0; if(a->neg && lo != 0) mpaddcfix(a, -1); }
// // right shift mpint by one // ignores sign and overflow // static void mprsh(Mpint *a) { long *a1, x, lo; int i, c; c = 0; lo = a->a[0] & 1; a1 = &a->a[Mpprec]; for(i=0; i<Mpprec; i++) { x = *--a1; *a1 = (x + c) >> 1; c = 0; if(x & 1) c = Mpbase; } if(a->neg && lo != 0) mpaddcfix(a, -1); }
// // fixed point input // required syntax is [+-][0[x]]d* // void mpatofix(Mpint *a, char *as) { int c, f; char *s, *s0; s = as; f = 0; mpmovecfix(a, 0); c = *s++; switch(c) { case '-': f = 1; case '+': c = *s++; if(c != '0') break; case '0': goto oct; } while(c) { if(c >= '0' && c <= '9') { mpmulcfix(a, 10); mpaddcfix(a, c-'0'); c = *s++; continue; } goto bad; } goto out; oct: c = *s++; if(c == 'x' || c == 'X') goto hex; while(c) { if(c >= '0' && c <= '7') { mpmulcfix(a, 8); mpaddcfix(a, c-'0'); c = *s++; continue; } goto bad; } goto out; hex: s0 = s; c = *s; while(c) { if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { s++; c = *s; continue; } goto bad; } mphextofix(a, s0, s-s0); if(a->ovf) goto bad; out: if(f) mpnegfix(a); return; bad: yyerror("constant too large: %s", as); mpmovecfix(a, 0); }
// // fixed point input // required syntax is [+-][0[x]]d* // void mpatofix(Mpint *a, char *as) { int c, f; char *s; s = as; f = 0; mpmovecfix(a, 0); c = *s++; switch(c) { case '-': f = 1; case '+': c = *s++; if(c != '0') break; case '0': goto oct; } while(c) { if(c >= '0' && c <= '9') { mpmulcfix(a, 10); mpaddcfix(a, c-'0'); c = *s++; continue; } goto bad; } goto out; oct: c = *s++; if(c == 'x' || c == 'X') goto hex; while(c) { if(c >= '0' && c <= '7') { mpmulcfix(a, 8); mpaddcfix(a, c-'0'); c = *s++; continue; } goto bad; } goto out; hex: c = *s++; while(c) { if(c >= '0' && c <= '9') { mpmulcfix(a, 16); mpaddcfix(a, c-'0'); c = *s++; continue; } if(c >= 'a' && c <= 'f') { mpmulcfix(a, 16); mpaddcfix(a, c+10-'a'); c = *s++; continue; } if(c >= 'A' && c <= 'F') { mpmulcfix(a, 16); mpaddcfix(a, c+10-'A'); c = *s++; continue; } goto bad; } out: if(f) mpnegfix(a); return; bad: yyerror("set ovf in mpatov: %s", as); mpmovecfix(a, 0); }