diff options
Diffstat (limited to 'big.c')
-rw-r--r-- | big.c | 38 |
1 files changed, 22 insertions, 16 deletions
@@ -356,24 +356,28 @@ 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 */ -word bigdiv(x, y) /* may assume y~=0 */ -word x, y; +/* may assume y~=0 */ +word bigdiv(word x, word y) { - word s1, s2, q; + word s1 = big_is_negative(y); + word s2 = s1; + /* make x,y positive and remember signs */ - if (s1 = big_is_negative(y)) + if (s1 = big_is_negative(y)) { y = make(INT, digit0(y), rest(y)); - if (big_is_negative(x)) - x = make(INT, digit0(x), rest(x)), s2 = !s1; - else - s2 = s1; + } + /* effect: s1 set iff y negative, s2 set iff signs mixed */ - if (rest(y)) - q = longdiv(x, y); - else - q = shortdiv(x, digit(y)); + if (big_is_negative(x)) { + x = make(INT, digit0(x), rest(x)); + s2 = !s1; + } + + word q = rest(y) ? longdiv(x, y) : shortdiv(x, digit(y)); + if (s2) { if (!bigzero(b_rem)) { x = q; @@ -382,14 +386,16 @@ word x, y; if (!rest(x)) { rest(x) = make(INT, 1, 0); break; - } else - x = rest(x); + } + x = rest(x); } } - if (!bigzero(q)) + if (!bigzero(q)) { digit(q) = SIGNBIT | digit(q); + } } - return (q); + + return q; } word bigmod(x, y) /* may assume y~=0 */ |