From 23d6f0e8e7725bcec50f5052709c8e241bc64eda Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 14 May 1991 12:06:49 +0000 Subject: Many small changes --- Objects/longobject.c | 65 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 17 deletions(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index e155608..a2fccc5 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -24,10 +24,20 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* Long (arbitrary precision) integer object implementation */ +/* XXX The functional organization of this file is terrible */ + #include "allobjects.h" #include "longintrepr.h" #include +static int ticker; /* XXX Could be shared with ceval? */ + +#define INTRCHECK(block) \ + if (--ticker < 0) { \ + ticker = 100; \ + if (intrcheck()) { block; } \ + } + /* Normalize (remove leading zeros from) a long int object. Doesn't attempt to free the storage--in most cases, due to the nature of the algorithms used, this could save at most be one word anyway. */ @@ -146,7 +156,7 @@ dgetlongvalue(vv) longobject * mul1(a, n) longobject *a; - digit n; + wdigit n; { return muladd1(a, n, (digit)0); } @@ -156,8 +166,8 @@ mul1(a, n) longobject * muladd1(a, n, extra) longobject *a; - digit n; - digit extra; + wdigit n; + wdigit extra; { int size_a = ABS(a->ob_size); longobject *z = alloclongobject(size_a+1); @@ -182,7 +192,7 @@ muladd1(a, n, extra) longobject * divrem1(a, n, prem) longobject *a; - digit n; + wdigit n; digit *prem; { int size = ABS(a->ob_size); @@ -253,12 +263,12 @@ long_format(a, base) *--p = rem; DECREF(a); a = temp; - if (a->ob_size >= INTRLIMIT && intrcheck()) { + INTRCHECK({ DECREF(a); DECREF(str); err_set(KeyboardInterrupt); return NULL; - } + }) } while (a->ob_size != 0); DECREF(a); if (sign) @@ -342,7 +352,8 @@ long_divrem(a, b, prem) return NULL; } if (size_a < size_b || - size_a == size_b && a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) { + size_a == size_b && + a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) { /* |a| < |b|. */ if (prem != NULL) { INCREF(a); @@ -376,7 +387,7 @@ long_divrem(a, b, prem) return z; } -/* True unsigned long division with remainder */ +/* Unsigned long division with remainder -- the algorithm */ static longobject * x_divrem(v1, w1, prem) @@ -399,7 +410,7 @@ x_divrem(v1, w1, prem) } assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */ - assert(v->refcnt == 1); /* Since v will be used as accumulator! */ + assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */ assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */ size_v = ABS(v->ob_size); @@ -408,15 +419,15 @@ x_divrem(v1, w1, prem) for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) { digit vj = (j >= size_v) ? 0 : v->ob_digit[j]; twodigits q; - long carry = 0; /* Signed! long! */ + stwodigits carry = 0; int i; - if (size_v >= INTRLIMIT && intrcheck()) { + INTRCHECK({ DECREF(a); a = NULL; err_set(KeyboardInterrupt); break; - } + }) if (vj == w->ob_digit[size_w-1]) q = MASK; else @@ -713,11 +724,11 @@ long_mul(a, w) twodigits f = a->ob_digit[i]; int j; - if (z->ob_size >= INTRLIMIT && intrcheck()) { + INTRCHECK({ DECREF(z); err_set(KeyboardInterrupt); return NULL; - } + }) for (j = 0; j < size_b; ++j) { carry += z->ob_digit[i+j] + b->ob_digit[j] * f; z->ob_digit[i+j] = carry & MASK; @@ -781,7 +792,8 @@ long_rem(v, w) 13 -10 3 -7 -13 -10 -3 -3 So, to get from rem to mod, we have to add b if a and b - have different signs. */ + have different signs. We then subtract one from the 'div' + part of the outcome to keep the invariant intact. */ static object * long_divmod(v, w) @@ -800,13 +812,24 @@ long_divmod(v, w) return NULL; } if ((v->ob_size < 0) != (((longobject *)w)->ob_size < 0)) { - longobject *temp = (longobject *) long_add(rem, w); + longobject *temp; + longobject *one; + temp = (longobject *) long_add(rem, w); DECREF(rem); - rem = temp; /* XXX ??? was rem = b ??? */ + rem = temp; if (rem == NULL) { DECREF(div); return NULL; } + one = (longobject *) newlongobject(1L); + if (one == NULL || + (temp = (longobject *) long_sub(div, one)) == NULL) { + DECREF(rem); + DECREF(div); + return NULL; + } + DECREF(div); + div = temp; } z = newtupleobject(2); if (z != NULL) { @@ -869,6 +892,13 @@ long_abs(v) return long_pos(v); } +static int +long_nonzero(v) + longobject *v; +{ + return v->ob_size != 0; +} + static number_methods long_as_number = { long_add, /*nb_add*/ long_sub, /*nb_subtract*/ @@ -880,6 +910,7 @@ static number_methods long_as_number = { long_neg, /*nb_negative*/ long_pos, /*tp_positive*/ long_abs, /*tp_absolute*/ + long_nonzero, /*tp_nonzero*/ }; typeobject Longtype = { -- cgit v0.12