Index: Include/longintrepr.h =================================================================== --- Include/longintrepr.h (révision 70631) +++ Include/longintrepr.h (copie de travail) @@ -97,6 +97,9 @@ /* Return a copy of src. */ PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src); +/* Number of digits (in base PyLong_BASE) */ +#define PyLong_NDIGITS(x) ((Py_SIZE(x) < 0)? -Py_SIZE(x) : Py_SIZE(x)) + #ifdef __cplusplus } #endif Index: Include/longobject.h =================================================================== --- Include/longobject.h (révision 70631) +++ Include/longobject.h (copie de travail) @@ -15,6 +15,12 @@ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) #define PyLong_CheckExact(op) (Py_TYPE(op) == &PyLong_Type) +/* True if x is negative */ +#define PyLong_IS_NEGATIVE(x) (Py_SIZE(x) < 0) + +/* True if x equals 0 */ +#define PyLong_IS_ZERO(x) (Py_SIZE(x) == 0) + PyAPI_FUNC(PyObject *) PyLong_FromLong(long); PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); PyAPI_FUNC(PyObject *) PyLong_FromDouble(double); Index: Objects/longobject.c =================================================================== --- Objects/longobject.c (révision 70631) +++ Objects/longobject.c (copie de travail) @@ -45,13 +45,13 @@ static PyLongObject * long_normalize(register PyLongObject *v) { - Py_ssize_t j = ABS(Py_SIZE(v)); + Py_ssize_t j = PyLong_NDIGITS(v); Py_ssize_t i = j; while (i > 0 && v->ob_digit[i-1] == 0) --i; if (i != j) - Py_SIZE(v) = (Py_SIZE(v) < 0) ? -(i) : i; + Py_SIZE(v) = PyLong_IS_NEGATIVE(v) ? -(i) : i; return v; } @@ -395,7 +395,7 @@ assert(v != NULL); assert(PyLong_Check(v)); - return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1); + return PyLong_IS_ZERO(v) ? 0 : (PyLong_IS_NEGATIVE(v) ? -1 : 1); } size_t @@ -407,7 +407,7 @@ assert(v != NULL); assert(PyLong_Check(v)); - ndigits = ABS(Py_SIZE(v)); + ndigits = PyLong_NDIGITS(v); assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); if (ndigits > 0) { digit msd = v->ob_digit[ndigits - 1]; @@ -559,7 +559,7 @@ assert(v != NULL && PyLong_Check(v)); - if (Py_SIZE(v) < 0) { + if (PyLong_IS_NEGATIVE(v)) { ndigits = -(Py_SIZE(v)); if (!is_signed) { PyErr_SetString(PyExc_OverflowError, @@ -1213,7 +1213,7 @@ static PyLongObject * divrem1(PyLongObject *a, digit n, digit *prem) { - const Py_ssize_t size = ABS(Py_SIZE(a)); + const Py_ssize_t size = PyLong_NDIGITS(a); PyLongObject *z; assert(n > 0 && n <= PyLong_MASK); @@ -1245,7 +1245,7 @@ return NULL; } assert(base >= 2 && base <= 36); - size_a = ABS(Py_SIZE(a)); + size_a = PyLong_NDIGITS(a); /* Compute a rough upper bound for the length of the string */ i = base; @@ -1797,7 +1797,7 @@ long_divrem(PyLongObject *a, PyLongObject *b, PyLongObject **pdiv, PyLongObject **prem) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); + Py_ssize_t size_a = PyLong_NDIGITS(a), size_b = PyLong_NDIGITS(b); PyLongObject *z; if (size_b == 0) { @@ -1845,7 +1845,7 @@ } /* Unsigned long division with remainder -- the algorithm. The arguments v1 - and w1 should satisfy 2 <= ABS(Py_SIZE(w1)) <= ABS(Py_SIZE(v1)). */ + and w1 should satisfy 2 <= PyLong_NDIGITS(w1) <= PyLong_NDIGITS(v1). */ static PyLongObject * x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) @@ -1865,8 +1865,8 @@ that won't overflow a digit. */ /* allocate space; w will also be used to hold the final remainder */ - size_v = ABS(Py_SIZE(v1)); - size_w = ABS(Py_SIZE(w1)); + size_v = PyLong_NDIGITS(v1); + size_w = PyLong_NDIGITS(w1); assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */ v = _PyLong_New(size_v+1); if (v == NULL) { @@ -1997,13 +1997,13 @@ Py_ssize_t sign; if (Py_SIZE(a) != Py_SIZE(b)) { - if (ABS(Py_SIZE(a)) == 0 && ABS(Py_SIZE(b)) == 0) + if (PyLong_IS_ZERO(a) && PyLong_IS_ZERO(b)) sign = 0; else sign = Py_SIZE(a) - Py_SIZE(b); } else { - Py_ssize_t i = ABS(Py_SIZE(a)); + Py_ssize_t i = PyLong_NDIGITS(a); while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) ; if (i < 0) @@ -2059,7 +2059,7 @@ static PyLongObject * x_add(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); + Py_ssize_t size_a = PyLong_NDIGITS(a), size_b = PyLong_NDIGITS(b); PyLongObject *z; Py_ssize_t i; digit carry = 0; @@ -2093,7 +2093,7 @@ static PyLongObject * x_sub(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); + Py_ssize_t size_a = PyLong_NDIGITS(a), size_b = PyLong_NDIGITS(b); PyLongObject *z; Py_ssize_t i; int sign = 1; @@ -2203,8 +2203,8 @@ x_mul(PyLongObject *a, PyLongObject *b) { PyLongObject *z; - Py_ssize_t size_a = ABS(Py_SIZE(a)); - Py_ssize_t size_b = ABS(Py_SIZE(b)); + Py_ssize_t size_a = PyLong_NDIGITS(a); + Py_ssize_t size_b = PyLong_NDIGITS(b); Py_ssize_t i; z = _PyLong_New(size_a + size_b); @@ -2295,7 +2295,7 @@ { PyLongObject *hi, *lo; Py_ssize_t size_lo, size_hi; - const Py_ssize_t size_n = ABS(Py_SIZE(n)); + const Py_ssize_t size_n = PyLong_NDIGITS(n); size_lo = MIN(size_n, size); size_hi = size_n - size_lo; @@ -2324,8 +2324,8 @@ static PyLongObject * k_mul(PyLongObject *a, PyLongObject *b) { - Py_ssize_t asize = ABS(Py_SIZE(a)); - Py_ssize_t bsize = ABS(Py_SIZE(b)); + Py_ssize_t asize = PyLong_NDIGITS(a); + Py_ssize_t bsize = PyLong_NDIGITS(b); PyLongObject *ah = NULL; PyLongObject *al = NULL; PyLongObject *bh = NULL; @@ -2545,8 +2545,8 @@ static PyLongObject * k_lopsided_mul(PyLongObject *a, PyLongObject *b) { - const Py_ssize_t asize = ABS(Py_SIZE(a)); - Py_ssize_t bsize = ABS(Py_SIZE(b)); + const Py_ssize_t asize = PyLong_NDIGITS(a); + Py_ssize_t bsize = PyLong_NDIGITS(b); Py_ssize_t nbdone; /* # of b digits already multiplied */ PyLongObject *ret; PyLongObject *bslice = NULL; @@ -2833,7 +2833,7 @@ return Py_NotImplemented; } - if (Py_SIZE(b) < 0) { /* if exponent is negative */ + if (PyLong_IS_NEGATIVE(b)) { /* if exponent is negative */ if (c) { PyErr_SetString(PyExc_TypeError, "pow() 2nd argument " "cannot be negative when 3rd argument specified"); @@ -2852,7 +2852,7 @@ if (c) { /* if modulus == 0: raise ValueError() */ - if (Py_SIZE(c) == 0) { + if (PyLong_IS_ZERO(c)) { PyErr_SetString(PyExc_ValueError, "pow() 3rd argument cannot be 0"); goto Error; @@ -2861,7 +2861,7 @@ /* if modulus < 0: negativeOutput = True modulus = -modulus */ - if (Py_SIZE(c) < 0) { + if (PyLong_IS_NEGATIVE(c)) { negativeOutput = 1; temp = (PyLongObject *)_PyLong_Copy(c); if (temp == NULL) @@ -2882,7 +2882,7 @@ /* if base < 0: base = base % modulus Having the base positive just makes things easier. */ - if (Py_SIZE(a) < 0) { + if (PyLong_IS_NEGATIVE(a)) { if (l_divmod(a, c, NULL, &temp) < 0) goto Error; Py_DECREF(a); @@ -2956,7 +2956,7 @@ } } - if (negativeOutput && (Py_SIZE(z) != 0)) { + if (negativeOutput && !PyLong_IS_ZERO(z)) { temp = (PyLongObject *)long_sub(z, c); if (temp == NULL) goto Error; @@ -3028,7 +3028,7 @@ static int long_nonzero(PyLongObject *v) { - return ABS(Py_SIZE(v)) != 0; + return !PyLong_IS_ZERO(v); } static PyObject * @@ -3042,7 +3042,7 @@ CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b); - if (Py_SIZE(a) < 0) { + if (PyLong_IS_NEGATIVE(a)) { /* Right shifting negative numbers is harder */ PyLongObject *a1, *a2; a1 = (PyLongObject *) long_invert(a); @@ -3066,7 +3066,7 @@ goto rshift_error; } wordshift = shiftby / PyLong_SHIFT; - newsize = ABS(Py_SIZE(a)) - wordshift; + newsize = PyLong_NDIGITS(a) - wordshift; if (newsize <= 0) { z = _PyLong_New(0); Py_DECREF(a); @@ -3080,7 +3080,7 @@ z = _PyLong_New(newsize); if (z == NULL) goto rshift_error; - if (Py_SIZE(a) < 0) + if (PyLong_IS_NEGATIVE(a)) Py_SIZE(z) = -(Py_SIZE(z)); for (i = 0, j = wordshift; i < newsize; i++, j++) { z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask; @@ -3168,7 +3168,7 @@ digit diga, digb; PyObject *v; - if (Py_SIZE(a) < 0) { + if (PyLong_IS_NEGATIVE(a)) { a = (PyLongObject *) long_invert(a); if (a == NULL) return NULL; @@ -3178,7 +3178,7 @@ Py_INCREF(a); maska = 0; } - if (Py_SIZE(b) < 0) { + if (PyLong_IS_NEGATIVE(b)) { b = (PyLongObject *) long_invert(b); if (b == NULL) { Py_DECREF(a); @@ -3497,7 +3497,7 @@ { Py_ssize_t res; - res = v->ob_type->tp_basicsize + ABS(Py_SIZE(v))*sizeof(digit); + res = v->ob_type->tp_basicsize + PyLong_NDIGITS(v)*sizeof(digit); return PyInt_FromSsize_t(res); } @@ -3511,7 +3511,7 @@ assert(v != NULL); assert(PyLong_Check(v)); - ndigits = ABS(Py_SIZE(v)); + ndigits = PyLong_NDIGITS(v); if (ndigits == 0) return PyInt_FromLong(0); Index: Modules/mathmodule.c =================================================================== --- Modules/mathmodule.c (révision 70631) +++ Modules/mathmodule.c (copie de travail) @@ -688,7 +688,7 @@ exp = PyLong_AsLong(oexp); if (exp == -1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - if (Py_SIZE(oexp) < 0) { + if (PyLong_IS_NEGATIVE(oexp)) { exp = LONG_MIN; } else {