From 69a209875107dce06174442d214c92f2fe748aae Mon Sep 17 00:00:00 2001 From: Jakob Kaivo Date: Mon, 28 Mar 2022 16:01:27 -0400 Subject: modify longdiv() and shortdiv() to return structs, eliminating another global, rename bigdiv() and bigmod() to big_divide() and big_remainder() to ensure no call sights are missed --- big.c | 61 +++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 26 deletions(-) (limited to 'big.c') diff --git a/big.c b/big.c index a30f890..4ea8726 100644 --- a/big.c +++ b/big.c @@ -24,16 +24,21 @@ #define OCTW 5 /* number of factors of 8 in IBASE */ #define DIGITWIDTH 15 +struct big_div { + word quo; + word rem; +}; + word big_one; static word big_plus(word, word, int); static word big_sub(word, word); static word len(word); -static word longdiv(word, word); +static struct big_div big__longdiv(word, word); +static struct big_div shortdiv(word, word); static word ms2d(word); static word msd(word); static word shift(word, word); -static word shortdiv(word, word); static word stimes(word, word); void bigsetup(void) @@ -359,11 +364,8 @@ word stimes(word x, word n) return r; } -/* TODO: make bigdiv()/bigmod() behave like div()/ldiv()/lldiv() */ -word b_rem; /* contains remainder from last call to longdiv or shortdiv */ - /* may assume y~=0 */ -word bigdiv(word x, word y) +word big_divide(word x, word y) { word s1 = big_is_negative(y); word s2 = s1; @@ -379,10 +381,11 @@ word bigdiv(word x, word y) s2 = !s1; } - word q = rest(y) ? longdiv(x, y) : shortdiv(x, digit(y)); + struct big_div bd = rest(y) ? big__longdiv(x, y) : shortdiv(x, digit(y)); + word q = bd.quo; if (s2) { - if (!bigzero(b_rem)) { + if (!bigzero(bd.rem)) { x = q; while ((digit(x) += 1) == IBASE) { /* add 1 to q in situ */ digit(x) = 0; @@ -402,7 +405,7 @@ word bigdiv(word x, word y) } /* may assume y~=0 */ -word bigmod(word x, word y) +word big_remainder(word x, word y) { word s1 = big_is_negative(y); word s2 = s1; @@ -412,24 +415,21 @@ word bigmod(word x, word y) y = make(INT, digit0(y), rest(y)); } + /* effect: s1 set iff y negative, s2 set iff signs mixed */ if (big_is_negative(x)) { x = make(INT, digit0(x), rest(x)); s2 = !s1; } - /* effect: s1 set iff y negative, s2 set iff signs mixed */ - if (rest(y)) { - longdiv(x, y); - } else { - shortdiv(x, digit(y)); - } + struct big_div bd = rest(y) ? big__longdiv(x, y) : shortdiv(x, digit(y)); if (s2) { - if (!bigzero(b_rem)) { - b_rem = bigsub(y, b_rem); + if (!bigzero(bd.rem)) { + bd.rem = bigsub(y, bd.rem); } } - return (s1 ? bignegate(b_rem) : b_rem); + + return (s1 ? bignegate(bd.rem) : bd.rem); } /* NB - above have entier based handling of signed cases (as Miranda) in @@ -444,7 +444,7 @@ word bigmod(word x, word y) /* divide big x by single digit n returning big quotient and setting external b_rem as side effect */ /* may assume - x>=0,n>0 */ -word shortdiv(word x, word n) +struct big_div shortdiv(word x, word n) { word d = digit(x); word q = 0; @@ -477,18 +477,24 @@ word shortdiv(word x, word n) q = tmp; } - b_rem = make(INT, s_rem, 0); - return q; + struct big_div bd = { + .quo = q, + .rem = make(INT, s_rem, 0), + }; + return bd; } /* divide big x by big y returning quotient, leaving remainder in extern variable b_rem */ /* may assume - x>=0,y>0 */ -word longdiv(word x, word y) +struct big_div big__longdiv(word x, word y) { if (bigcmp(x, y) < 0) { - b_rem = x; - return (make(INT, 0, 0)); + struct big_div bd = { + .quo = make(INT, 0, 0), + .rem = x, + }; + return bd; } word y1 = msd(y); @@ -546,8 +552,11 @@ word longdiv(word x, word y) q = make(INT, d, q); if (n-- == 0) { - b_rem = scale == 1 ? x : shortdiv(x, scale); - return (q); + struct big_div bd = { + .quo = q, + .rem = scale == 1 ? x : shortdiv(x, scale).rem, + }; + return bd; } ly--; y = rest(y); -- cgit v1.2.1