Commit 23d6f0e8 authored by Guido van Rossum's avatar Guido van Rossum

Many small changes

parent badb116f
...@@ -24,10 +24,20 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ...@@ -24,10 +24,20 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Long (arbitrary precision) integer object implementation */ /* Long (arbitrary precision) integer object implementation */
/* XXX The functional organization of this file is terrible */
#include "allobjects.h" #include "allobjects.h"
#include "longintrepr.h" #include "longintrepr.h"
#include <assert.h> #include <assert.h>
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. /* Normalize (remove leading zeros from) a long int object.
Doesn't attempt to free the storage--in most cases, due to the nature 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. */ of the algorithms used, this could save at most be one word anyway. */
...@@ -146,7 +156,7 @@ dgetlongvalue(vv) ...@@ -146,7 +156,7 @@ dgetlongvalue(vv)
longobject * longobject *
mul1(a, n) mul1(a, n)
longobject *a; longobject *a;
digit n; wdigit n;
{ {
return muladd1(a, n, (digit)0); return muladd1(a, n, (digit)0);
} }
...@@ -156,8 +166,8 @@ mul1(a, n) ...@@ -156,8 +166,8 @@ mul1(a, n)
longobject * longobject *
muladd1(a, n, extra) muladd1(a, n, extra)
longobject *a; longobject *a;
digit n; wdigit n;
digit extra; wdigit extra;
{ {
int size_a = ABS(a->ob_size); int size_a = ABS(a->ob_size);
longobject *z = alloclongobject(size_a+1); longobject *z = alloclongobject(size_a+1);
...@@ -182,7 +192,7 @@ muladd1(a, n, extra) ...@@ -182,7 +192,7 @@ muladd1(a, n, extra)
longobject * longobject *
divrem1(a, n, prem) divrem1(a, n, prem)
longobject *a; longobject *a;
digit n; wdigit n;
digit *prem; digit *prem;
{ {
int size = ABS(a->ob_size); int size = ABS(a->ob_size);
...@@ -253,12 +263,12 @@ long_format(a, base) ...@@ -253,12 +263,12 @@ long_format(a, base)
*--p = rem; *--p = rem;
DECREF(a); DECREF(a);
a = temp; a = temp;
if (a->ob_size >= INTRLIMIT && intrcheck()) { INTRCHECK({
DECREF(a); DECREF(a);
DECREF(str); DECREF(str);
err_set(KeyboardInterrupt); err_set(KeyboardInterrupt);
return NULL; return NULL;
} })
} while (a->ob_size != 0); } while (a->ob_size != 0);
DECREF(a); DECREF(a);
if (sign) if (sign)
...@@ -342,7 +352,8 @@ long_divrem(a, b, prem) ...@@ -342,7 +352,8 @@ long_divrem(a, b, prem)
return NULL; return NULL;
} }
if (size_a < size_b || 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|. */ /* |a| < |b|. */
if (prem != NULL) { if (prem != NULL) {
INCREF(a); INCREF(a);
...@@ -376,7 +387,7 @@ long_divrem(a, b, prem) ...@@ -376,7 +387,7 @@ long_divrem(a, b, prem)
return z; return z;
} }
/* True unsigned long division with remainder */ /* Unsigned long division with remainder -- the algorithm */
static longobject * static longobject *
x_divrem(v1, w1, prem) x_divrem(v1, w1, prem)
...@@ -399,7 +410,7 @@ 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(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 */ assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
size_v = ABS(v->ob_size); size_v = ABS(v->ob_size);
...@@ -408,15 +419,15 @@ x_divrem(v1, w1, prem) ...@@ -408,15 +419,15 @@ x_divrem(v1, w1, prem)
for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) { 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]; digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
twodigits q; twodigits q;
long carry = 0; /* Signed! long! */ stwodigits carry = 0;
int i; int i;
if (size_v >= INTRLIMIT && intrcheck()) { INTRCHECK({
DECREF(a); DECREF(a);
a = NULL; a = NULL;
err_set(KeyboardInterrupt); err_set(KeyboardInterrupt);
break; break;
} })
if (vj == w->ob_digit[size_w-1]) if (vj == w->ob_digit[size_w-1])
q = MASK; q = MASK;
else else
...@@ -713,11 +724,11 @@ long_mul(a, w) ...@@ -713,11 +724,11 @@ long_mul(a, w)
twodigits f = a->ob_digit[i]; twodigits f = a->ob_digit[i];
int j; int j;
if (z->ob_size >= INTRLIMIT && intrcheck()) { INTRCHECK({
DECREF(z); DECREF(z);
err_set(KeyboardInterrupt); err_set(KeyboardInterrupt);
return NULL; return NULL;
} })
for (j = 0; j < size_b; ++j) { for (j = 0; j < size_b; ++j) {
carry += z->ob_digit[i+j] + b->ob_digit[j] * f; carry += z->ob_digit[i+j] + b->ob_digit[j] * f;
z->ob_digit[i+j] = carry & MASK; z->ob_digit[i+j] = carry & MASK;
...@@ -781,7 +792,8 @@ long_rem(v, w) ...@@ -781,7 +792,8 @@ long_rem(v, w)
13 -10 3 -7 13 -10 3 -7
-13 -10 -3 -3 -13 -10 -3 -3
So, to get from rem to mod, we have to add b if a and b 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 * static object *
long_divmod(v, w) long_divmod(v, w)
...@@ -800,13 +812,24 @@ long_divmod(v, w) ...@@ -800,13 +812,24 @@ long_divmod(v, w)
return NULL; return NULL;
} }
if ((v->ob_size < 0) != (((longobject *)w)->ob_size < 0)) { 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); DECREF(rem);
rem = temp; /* XXX ??? was rem = b ??? */ rem = temp;
if (rem == NULL) { if (rem == NULL) {
DECREF(div); DECREF(div);
return NULL; 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); z = newtupleobject(2);
if (z != NULL) { if (z != NULL) {
...@@ -869,6 +892,13 @@ long_abs(v) ...@@ -869,6 +892,13 @@ long_abs(v)
return long_pos(v); return long_pos(v);
} }
static int
long_nonzero(v)
longobject *v;
{
return v->ob_size != 0;
}
static number_methods long_as_number = { static number_methods long_as_number = {
long_add, /*nb_add*/ long_add, /*nb_add*/
long_sub, /*nb_subtract*/ long_sub, /*nb_subtract*/
...@@ -880,6 +910,7 @@ static number_methods long_as_number = { ...@@ -880,6 +910,7 @@ static number_methods long_as_number = {
long_neg, /*nb_negative*/ long_neg, /*nb_negative*/
long_pos, /*tp_positive*/ long_pos, /*tp_positive*/
long_abs, /*tp_absolute*/ long_abs, /*tp_absolute*/
long_nonzero, /*tp_nonzero*/
}; };
typeobject Longtype = { typeobject Longtype = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment