diff options
Diffstat (limited to 'Objects/longobject.c')
| -rw-r--r-- | Objects/longobject.c | 373 |
1 files changed, 261 insertions, 112 deletions
diff --git a/Objects/longobject.c b/Objects/longobject.c index 9b62d92..740b7f5 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -721,7 +721,7 @@ _PyLong_NumBits(PyObject *vv) assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); if (ndigits > 0) { digit msd = v->ob_digit[ndigits - 1]; - if ((size_t)(ndigits - 1) > PY_SIZE_MAX / (size_t)PyLong_SHIFT) + if ((size_t)(ndigits - 1) > SIZE_MAX / (size_t)PyLong_SHIFT) goto Overflow; result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT; do { @@ -989,16 +989,13 @@ PyObject * PyLong_FromVoidPtr(void *p) { #if SIZEOF_VOID_P <= SIZEOF_LONG - return PyLong_FromUnsignedLong((unsigned long)(Py_uintptr_t)p); + return PyLong_FromUnsignedLong((unsigned long)(uintptr_t)p); #else -#ifndef HAVE_LONG_LONG -# error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long" -#endif #if SIZEOF_LONG_LONG < SIZEOF_VOID_P -# error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)" +# error "PyLong_FromVoidPtr: sizeof(long long) < sizeof(void*)" #endif - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)(Py_uintptr_t)p); + return PyLong_FromUnsignedLongLong((unsigned long long)(uintptr_t)p); #endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ } @@ -1017,13 +1014,10 @@ PyLong_AsVoidPtr(PyObject *vv) x = PyLong_AsUnsignedLong(vv); #else -#ifndef HAVE_LONG_LONG -# error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long" -#endif #if SIZEOF_LONG_LONG < SIZEOF_VOID_P -# error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)" +# error "PyLong_AsVoidPtr: sizeof(long long) < sizeof(void*)" #endif - PY_LONG_LONG x; + long long x; if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) x = PyLong_AsLongLong(vv); @@ -1037,22 +1031,20 @@ PyLong_AsVoidPtr(PyObject *vv) return (void *)x; } -#ifdef HAVE_LONG_LONG - -/* Initial PY_LONG_LONG support by Chris Herborth (chrish@qnx.com), later +/* Initial long long support by Chris Herborth (chrish@qnx.com), later * rewritten to use the newer PyLong_{As,From}ByteArray API. */ -#define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN) +#define PY_ABS_LLONG_MIN (0-(unsigned long long)PY_LLONG_MIN) -/* Create a new int object from a C PY_LONG_LONG int. */ +/* Create a new int object from a C long long int. */ PyObject * -PyLong_FromLongLong(PY_LONG_LONG ival) +PyLong_FromLongLong(long long ival) { PyLongObject *v; - unsigned PY_LONG_LONG abs_ival; - unsigned PY_LONG_LONG t; /* unsigned so >> doesn't propagate sign bit */ + unsigned long long abs_ival; + unsigned long long t; /* unsigned so >> doesn't propagate sign bit */ int ndigits = 0; int negative = 0; @@ -1060,11 +1052,11 @@ PyLong_FromLongLong(PY_LONG_LONG ival) if (ival < 0) { /* avoid signed overflow on negation; see comments in PyLong_FromLong above. */ - abs_ival = (unsigned PY_LONG_LONG)(-1-ival) + 1; + abs_ival = (unsigned long long)(-1-ival) + 1; negative = 1; } else { - abs_ival = (unsigned PY_LONG_LONG)ival; + abs_ival = (unsigned long long)ival; } /* Count the number of Python digits. @@ -1089,19 +1081,19 @@ PyLong_FromLongLong(PY_LONG_LONG ival) return (PyObject *)v; } -/* Create a new int object from a C unsigned PY_LONG_LONG int. */ +/* Create a new int object from a C unsigned long long int. */ PyObject * -PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival) +PyLong_FromUnsignedLongLong(unsigned long long ival) { PyLongObject *v; - unsigned PY_LONG_LONG t; + unsigned long long t; int ndigits = 0; if (ival < PyLong_BASE) return PyLong_FromLong((long)ival); /* Count the number of Python digits. */ - t = (unsigned PY_LONG_LONG)ival; + t = (unsigned long long)ival; while (t) { ++ndigits; t >>= PyLong_SHIFT; @@ -1190,11 +1182,11 @@ PyLong_FromSize_t(size_t ival) /* Get a C long long int from an int object or any object that has an __int__ method. Return -1 and set an error if overflow occurs. */ -PY_LONG_LONG +long long PyLong_AsLongLong(PyObject *vv) { PyLongObject *v; - PY_LONG_LONG bytes; + long long bytes; int res; int do_decref = 0; /* if nb_int was called */ @@ -1232,30 +1224,30 @@ PyLong_AsLongLong(PyObject *vv) Py_DECREF(v); } - /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ + /* Plan 9 can't handle long long in ? : expressions */ if (res < 0) - return (PY_LONG_LONG)-1; + return (long long)-1; else return bytes; } -/* Get a C unsigned PY_LONG_LONG int from an int object. +/* Get a C unsigned long long int from an int object. Return -1 and set an error if overflow occurs. */ -unsigned PY_LONG_LONG +unsigned long long PyLong_AsUnsignedLongLong(PyObject *vv) { PyLongObject *v; - unsigned PY_LONG_LONG bytes; + unsigned long long bytes; int res; if (vv == NULL) { PyErr_BadInternalCall(); - return (unsigned PY_LONG_LONG)-1; + return (unsigned long long)-1; } if (!PyLong_Check(vv)) { PyErr_SetString(PyExc_TypeError, "an integer is required"); - return (unsigned PY_LONG_LONG)-1; + return (unsigned long long)-1; } v = (PyLongObject*)vv; @@ -1267,9 +1259,9 @@ PyLong_AsUnsignedLongLong(PyObject *vv) res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 0); - /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ + /* Plan 9 can't handle long long in ? : expressions */ if (res < 0) - return (unsigned PY_LONG_LONG)res; + return (unsigned long long)res; else return bytes; } @@ -1277,11 +1269,11 @@ PyLong_AsUnsignedLongLong(PyObject *vv) /* Get a C unsigned long int from an int object, ignoring the high bits. Returns -1 and sets an error condition if an error occurs. */ -static unsigned PY_LONG_LONG +static unsigned long long _PyLong_AsUnsignedLongLongMask(PyObject *vv) { PyLongObject *v; - unsigned PY_LONG_LONG x; + unsigned long long x; Py_ssize_t i; int sign; @@ -1307,11 +1299,11 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) return x * sign; } -unsigned PY_LONG_LONG +unsigned long long PyLong_AsUnsignedLongLongMask(PyObject *op) { PyLongObject *lo; - unsigned PY_LONG_LONG val; + unsigned long long val; if (op == NULL) { PyErr_BadInternalCall(); @@ -1324,7 +1316,7 @@ PyLong_AsUnsignedLongLongMask(PyObject *op) lo = _PyLong_FromNbInt(op); if (lo == NULL) - return (unsigned PY_LONG_LONG)-1; + return (unsigned long long)-1; val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo); Py_DECREF(lo); @@ -1341,13 +1333,13 @@ PyLong_AsUnsignedLongLongMask(PyObject *op) In this case *overflow will be 0. */ -PY_LONG_LONG +long long PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) { /* This version by Tim Peters */ PyLongObject *v; - unsigned PY_LONG_LONG x, prev; - PY_LONG_LONG res; + unsigned long long x, prev; + long long res; Py_ssize_t i; int sign; int do_decref = 0; /* if nb_int was called */ @@ -1399,8 +1391,8 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) /* Haven't lost any bits, but casting to long requires extra * care (see comment above). */ - if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) { - res = (PY_LONG_LONG)x * sign; + if (x <= (unsigned long long)PY_LLONG_MAX) { + res = (long long)x * sign; } else if (sign < 0 && x == PY_ABS_LLONG_MIN) { res = PY_LLONG_MIN; @@ -1417,8 +1409,6 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) return res; } -#endif /* HAVE_LONG_LONG */ - #define CHECK_BINOP(v,w) \ do { \ if (!PyLong_Check(v) || !PyLong_Check(w)) \ @@ -1582,13 +1572,16 @@ divrem1(PyLongObject *a, digit n, digit *prem) static int long_to_decimal_string_internal(PyObject *aa, PyObject **p_output, - _PyUnicodeWriter *writer) + _PyUnicodeWriter *writer, + _PyBytesWriter *bytes_writer, + char **bytes_str) { PyLongObject *scratch, *a; - PyObject *str; + PyObject *str = NULL; Py_ssize_t size, strlen, size_a, i, j; digit *pout, *pin, rem, tenpow; int negative; + int d; enum PyUnicode_Kind kind; a = (PyLongObject *)aa; @@ -1606,15 +1599,17 @@ long_to_decimal_string_internal(PyObject *aa, But log2(a) < size_a * PyLong_SHIFT, and log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT - > 3 * _PyLong_DECIMAL_SHIFT + > 3.3 * _PyLong_DECIMAL_SHIFT + + size_a * PyLong_SHIFT / (3.3 * _PyLong_DECIMAL_SHIFT) = + size_a + size_a / d < size_a + size_a / floor(d), + where d = (3.3 * _PyLong_DECIMAL_SHIFT) / + (PyLong_SHIFT - 3.3 * _PyLong_DECIMAL_SHIFT) */ - if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) { - PyErr_SetString(PyExc_OverflowError, - "int too large to format"); - return -1; - } - /* the expression size_a * PyLong_SHIFT is now safe from overflow */ - size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT); + d = (33 * _PyLong_DECIMAL_SHIFT) / + (10 * PyLong_SHIFT - 33 * _PyLong_DECIMAL_SHIFT); + assert(size_a < PY_SSIZE_T_MAX/2); + size = 1 + size_a + size_a / d; scratch = _PyLong_New(size); if (scratch == NULL) return -1; @@ -1662,7 +1657,13 @@ long_to_decimal_string_internal(PyObject *aa, return -1; } kind = writer->kind; - str = NULL; + } + else if (bytes_writer) { + *bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, strlen); + if (*bytes_str == NULL) { + Py_DECREF(scratch); + return -1; + } } else { str = PyUnicode_New(strlen, '9'); @@ -1673,13 +1674,8 @@ long_to_decimal_string_internal(PyObject *aa, kind = PyUnicode_KIND(str); } -#define WRITE_DIGITS(TYPE) \ +#define WRITE_DIGITS(p) \ do { \ - if (writer) \ - p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + strlen; \ - else \ - p = (TYPE*)PyUnicode_DATA(str) + strlen; \ - \ /* pout[0] through pout[size-2] contribute exactly \ _PyLong_DECIMAL_SHIFT digits each */ \ for (i=0; i < size - 1; i++) { \ @@ -1699,6 +1695,16 @@ long_to_decimal_string_internal(PyObject *aa, /* and sign */ \ if (negative) \ *--p = '-'; \ + } while (0) + +#define WRITE_UNICODE_DIGITS(TYPE) \ + do { \ + if (writer) \ + p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + strlen; \ + else \ + p = (TYPE*)PyUnicode_DATA(str) + strlen; \ + \ + WRITE_DIGITS(p); \ \ /* check we've counted correctly */ \ if (writer) \ @@ -1708,25 +1714,34 @@ long_to_decimal_string_internal(PyObject *aa, } while (0) /* fill the string right-to-left */ - if (kind == PyUnicode_1BYTE_KIND) { + if (bytes_writer) { + char *p = *bytes_str + strlen; + WRITE_DIGITS(p); + assert(p == *bytes_str); + } + else if (kind == PyUnicode_1BYTE_KIND) { Py_UCS1 *p; - WRITE_DIGITS(Py_UCS1); + WRITE_UNICODE_DIGITS(Py_UCS1); } else if (kind == PyUnicode_2BYTE_KIND) { Py_UCS2 *p; - WRITE_DIGITS(Py_UCS2); + WRITE_UNICODE_DIGITS(Py_UCS2); } else { Py_UCS4 *p; assert (kind == PyUnicode_4BYTE_KIND); - WRITE_DIGITS(Py_UCS4); + WRITE_UNICODE_DIGITS(Py_UCS4); } #undef WRITE_DIGITS +#undef WRITE_UNICODE_DIGITS Py_DECREF(scratch); if (writer) { writer->pos += strlen; } + else if (bytes_writer) { + (*bytes_str) += strlen; + } else { assert(_PyUnicode_CheckConsistency(str, 1)); *p_output = (PyObject *)str; @@ -1738,7 +1753,7 @@ static PyObject * long_to_decimal_string(PyObject *aa) { PyObject *v; - if (long_to_decimal_string_internal(aa, &v, NULL) == -1) + if (long_to_decimal_string_internal(aa, &v, NULL, NULL, NULL) == -1) return NULL; return v; } @@ -1750,10 +1765,11 @@ long_to_decimal_string(PyObject *aa) static int long_format_binary(PyObject *aa, int base, int alternate, - PyObject **p_output, _PyUnicodeWriter *writer) + PyObject **p_output, _PyUnicodeWriter *writer, + _PyBytesWriter *bytes_writer, char **bytes_str) { PyLongObject *a = (PyLongObject *)aa; - PyObject *v; + PyObject *v = NULL; Py_ssize_t sz; Py_ssize_t size_a; enum PyUnicode_Kind kind; @@ -1810,7 +1826,11 @@ long_format_binary(PyObject *aa, int base, int alternate, if (_PyUnicodeWriter_Prepare(writer, sz, 'x') == -1) return -1; kind = writer->kind; - v = NULL; + } + else if (bytes_writer) { + *bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, sz); + if (*bytes_str == NULL) + return -1; } else { v = PyUnicode_New(sz, 'x'); @@ -1819,13 +1839,8 @@ long_format_binary(PyObject *aa, int base, int alternate, kind = PyUnicode_KIND(v); } -#define WRITE_DIGITS(TYPE) \ +#define WRITE_DIGITS(p) \ do { \ - if (writer) \ - p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + sz; \ - else \ - p = (TYPE*)PyUnicode_DATA(v) + sz; \ - \ if (size_a == 0) { \ *--p = '0'; \ } \ @@ -1860,30 +1875,50 @@ long_format_binary(PyObject *aa, int base, int alternate, } \ if (negative) \ *--p = '-'; \ + } while (0) + +#define WRITE_UNICODE_DIGITS(TYPE) \ + do { \ + if (writer) \ + p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + sz; \ + else \ + p = (TYPE*)PyUnicode_DATA(v) + sz; \ + \ + WRITE_DIGITS(p); \ + \ if (writer) \ assert(p == ((TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos)); \ else \ assert(p == (TYPE*)PyUnicode_DATA(v)); \ } while (0) - if (kind == PyUnicode_1BYTE_KIND) { + if (bytes_writer) { + char *p = *bytes_str + sz; + WRITE_DIGITS(p); + assert(p == *bytes_str); + } + else if (kind == PyUnicode_1BYTE_KIND) { Py_UCS1 *p; - WRITE_DIGITS(Py_UCS1); + WRITE_UNICODE_DIGITS(Py_UCS1); } else if (kind == PyUnicode_2BYTE_KIND) { Py_UCS2 *p; - WRITE_DIGITS(Py_UCS2); + WRITE_UNICODE_DIGITS(Py_UCS2); } else { Py_UCS4 *p; assert (kind == PyUnicode_4BYTE_KIND); - WRITE_DIGITS(Py_UCS4); + WRITE_UNICODE_DIGITS(Py_UCS4); } #undef WRITE_DIGITS +#undef WRITE_UNICODE_DIGITS if (writer) { writer->pos += sz; } + else if (bytes_writer) { + (*bytes_str) += sz; + } else { assert(_PyUnicode_CheckConsistency(v, 1)); *p_output = v; @@ -1897,9 +1932,9 @@ _PyLong_Format(PyObject *obj, int base) PyObject *str; int err; if (base == 10) - err = long_to_decimal_string_internal(obj, &str, NULL); + err = long_to_decimal_string_internal(obj, &str, NULL, NULL, NULL); else - err = long_format_binary(obj, base, 1, &str, NULL); + err = long_format_binary(obj, base, 1, &str, NULL, NULL, NULL); if (err == -1) return NULL; return str; @@ -1911,9 +1946,31 @@ _PyLong_FormatWriter(_PyUnicodeWriter *writer, int base, int alternate) { if (base == 10) - return long_to_decimal_string_internal(obj, NULL, writer); + return long_to_decimal_string_internal(obj, NULL, writer, + NULL, NULL); else - return long_format_binary(obj, base, alternate, NULL, writer); + return long_format_binary(obj, base, alternate, NULL, writer, + NULL, NULL); +} + +char* +_PyLong_FormatBytesWriter(_PyBytesWriter *writer, char *str, + PyObject *obj, + int base, int alternate) +{ + char *str2; + int res; + str2 = str; + if (base == 10) + res = long_to_decimal_string_internal(obj, NULL, NULL, + writer, &str2); + else + res = long_format_binary(obj, base, alternate, NULL, NULL, + writer, &str2); + if (res < 0) + return NULL; + assert(str2 != NULL); + return str2; } /* Table of digit values for 8-bit string -> integer conversion. @@ -2394,8 +2451,11 @@ long_divrem(PyLongObject *a, PyLongObject *b, *pdiv = (PyLongObject*)PyLong_FromLong(0); if (*pdiv == NULL) return -1; - Py_INCREF(a); - *prem = (PyLongObject *) a; + *prem = (PyLongObject *)long_long((PyObject *)a); + if (*prem == NULL) { + Py_CLEAR(*pdiv); + return -1; + } return 0; } if (size_b == 1) { @@ -2705,6 +2765,13 @@ PyLong_AsDouble(PyObject *v) PyErr_SetString(PyExc_TypeError, "an integer is required"); return -1.0; } + if (Py_ABS(Py_SIZE(v)) <= 1) { + /* Fast path; single digit long (31 bits) will cast safely + to double. This improves performance of FP/long operations + by 20%. + */ + return (double)MEDIUM_VALUE((PyLongObject *)v); + } x = _PyLong_Frexp((PyLongObject *)v, &exponent); if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) { PyErr_SetString(PyExc_OverflowError, @@ -2929,9 +2996,7 @@ x_sub(PyLongObject *a, PyLongObject *b) } assert(borrow == 0); if (sign < 0) { - _PyLong_Negate(&z); - if (z == NULL) - return NULL; + Py_SIZE(z) = -Py_SIZE(z); } return long_normalize(z); } @@ -2951,8 +3016,14 @@ long_add(PyLongObject *a, PyLongObject *b) if (Py_SIZE(a) < 0) { if (Py_SIZE(b) < 0) { z = x_add(a, b); - if (z != NULL && Py_SIZE(z) != 0) + if (z != NULL) { + /* x_add received at least one multiple-digit int, + and thus z must be a multiple-digit int. + That also means z is not an element of + small_ints, so negating it in-place is safe. */ + assert(Py_REFCNT(z) == 1); Py_SIZE(z) = -(Py_SIZE(z)); + } } else z = x_sub(b, a); @@ -2983,8 +3054,10 @@ long_sub(PyLongObject *a, PyLongObject *b) z = x_sub(a, b); else z = x_add(a, b); - if (z != NULL && Py_SIZE(z) != 0) + if (z != NULL) { + assert(Py_SIZE(z) == 0 || Py_REFCNT(z) == 1); Py_SIZE(z) = -(Py_SIZE(z)); + } } else { if (Py_SIZE(b) < 0) @@ -3408,17 +3481,7 @@ long_mul(PyLongObject *a, PyLongObject *b) /* fast path for single-digit multiplication */ if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { stwodigits v = (stwodigits)(MEDIUM_VALUE(a)) * MEDIUM_VALUE(b); -#ifdef HAVE_LONG_LONG - return PyLong_FromLongLong((PY_LONG_LONG)v); -#else - /* if we don't have long long then we're almost certainly - using 15-bit digits, so v will fit in a long. In the - unlikely event that we're using 30-bit digits on a platform - without long long, a large v will just cause us to fall - through to the general multiplication code below. */ - if (v >= LONG_MIN && v <= LONG_MAX) - return PyLong_FromLong((long)v); -#endif + return PyLong_FromLongLong((long long)v); } z = k_mul(a, b); @@ -3431,6 +3494,52 @@ long_mul(PyLongObject *a, PyLongObject *b) return (PyObject *)z; } +/* Fast modulo division for single-digit longs. */ +static PyObject * +fast_mod(PyLongObject *a, PyLongObject *b) +{ + sdigit left = a->ob_digit[0]; + sdigit right = b->ob_digit[0]; + sdigit mod; + + assert(Py_ABS(Py_SIZE(a)) == 1); + assert(Py_ABS(Py_SIZE(b)) == 1); + + if (Py_SIZE(a) == Py_SIZE(b)) { + /* 'a' and 'b' have the same sign. */ + mod = left % right; + } + else { + /* Either 'a' or 'b' is negative. */ + mod = right - 1 - (left - 1) % right; + } + + return PyLong_FromLong(mod * (sdigit)Py_SIZE(b)); +} + +/* Fast floor division for single-digit longs. */ +static PyObject * +fast_floor_div(PyLongObject *a, PyLongObject *b) +{ + sdigit left = a->ob_digit[0]; + sdigit right = b->ob_digit[0]; + sdigit div; + + assert(Py_ABS(Py_SIZE(a)) == 1); + assert(Py_ABS(Py_SIZE(b)) == 1); + + if (Py_SIZE(a) == Py_SIZE(b)) { + /* 'a' and 'b' have the same sign. */ + div = left / right; + } + else { + /* Either 'a' or 'b' is negative. */ + div = -1 - (left - 1) / right; + } + + return PyLong_FromLong(div); +} + /* The / and % operators are now defined in terms of divmod(). The expression a mod b has the value a - b*floor(a/b). The long_divrem function gives the remainder after division of @@ -3458,6 +3567,30 @@ l_divmod(PyLongObject *v, PyLongObject *w, { PyLongObject *div, *mod; + if (Py_ABS(Py_SIZE(v)) == 1 && Py_ABS(Py_SIZE(w)) == 1) { + /* Fast path for single-digit longs */ + div = NULL; + if (pdiv != NULL) { + div = (PyLongObject *)fast_floor_div(v, w); + if (div == NULL) { + return -1; + } + } + if (pmod != NULL) { + mod = (PyLongObject *)fast_mod(v, w); + if (mod == NULL) { + Py_XDECREF(div); + return -1; + } + *pmod = mod; + } + if (pdiv != NULL) { + /* We only want to set `*pdiv` when `*pmod` is + set successfully. */ + *pdiv = div; + } + return 0; + } if (long_divrem(v, w, &div, &mod) < 0) return -1; if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) || @@ -3502,6 +3635,11 @@ long_div(PyObject *a, PyObject *b) PyLongObject *div; CHECK_BINOP(a, b); + + if (Py_ABS(Py_SIZE(a)) == 1 && Py_ABS(Py_SIZE(b)) == 1) { + return fast_floor_div((PyLongObject*)a, (PyLongObject*)b); + } + if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, NULL) < 0) div = NULL; return (PyObject *)div; @@ -3741,9 +3879,9 @@ long_true_divide(PyObject *v, PyObject *w) /* Round by directly modifying the low digit of x. */ mask = (digit)1 << (extra_bits - 1); low = x->ob_digit[0] | inexact; - if (low & mask && low & (3*mask-1)) + if ((low & mask) && (low & (3U*mask-1U))) low += mask; - x->ob_digit[0] = low & ~(mask-1U); + x->ob_digit[0] = low & ~(2U*mask-1U); /* Convert x to a double dx; the conversion is exact. */ dx = x->ob_digit[--x_size]; @@ -3777,6 +3915,10 @@ long_mod(PyObject *a, PyObject *b) CHECK_BINOP(a, b); + if (Py_ABS(Py_SIZE(a)) == 1 && Py_ABS(Py_SIZE(b)) == 1) { + return fast_mod((PyLongObject*)a, (PyLongObject*)b); + } + if (l_divmod((PyLongObject*)a, (PyLongObject*)b, NULL, &mod) < 0) mod = NULL; return (PyObject *)mod; @@ -4011,8 +4153,10 @@ long_invert(PyLongObject *v) Py_DECREF(w); if (x == NULL) return NULL; - Py_SIZE(x) = -(Py_SIZE(x)); - return (PyObject *)maybe_small_long(x); + _PyLong_Negate(&x); + /* No need for maybe_small_long here, since any small + longs will have been caught in the Py_SIZE <= 1 fast path. */ + return (PyObject *)x; } static PyObject * @@ -4117,6 +4261,11 @@ long_lshift(PyObject *v, PyObject *w) PyErr_SetString(PyExc_ValueError, "negative shift count"); return NULL; } + + if (Py_SIZE(a) == 0) { + return PyLong_FromLong(0); + } + /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ wordshift = shiftby / PyLong_SHIFT; remshift = shiftby - wordshift * PyLong_SHIFT; @@ -4501,7 +4650,7 @@ simple: /* a fits into a long, so b must too */ x = PyLong_AsLong((PyObject *)a); y = PyLong_AsLong((PyObject *)b); -#elif defined(PY_LONG_LONG) && PY_LLONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT +#elif PY_LLONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT x = PyLong_AsLongLong((PyObject *)a); y = PyLong_AsLongLong((PyObject *)b); #else @@ -4520,7 +4669,7 @@ simple: } #if LONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT return PyLong_FromLong(x); -#elif defined(PY_LONG_LONG) && PY_LLONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT +#elif PY_LLONG_MAX >> PyLong_SHIFT >> PyLong_SHIFT return PyLong_FromLongLong(x); #else # error "_PyLong_GCD" |
