summaryrefslogtreecommitdiff
path: root/Objects/longobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/longobject.c')
-rw-r--r--Objects/longobject.c93
1 files changed, 40 insertions, 53 deletions
diff --git a/Objects/longobject.c b/Objects/longobject.c
index ad239ce84e..c95f9467ad 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -315,7 +315,6 @@ PyLong_FromUnsignedLong(unsigned long ival)
v = _PyLong_New(ndigits);
if (v != NULL) {
digit *p = v->ob_digit;
- Py_SIZE(v) = ndigits;
while (ival) {
*p++ = (digit)(ival & PyLong_MASK);
ival >>= PyLong_SHIFT;
@@ -709,12 +708,33 @@ _PyLong_Sign(PyObject *vv)
return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1);
}
+/* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d <
+ 2**k if d is nonzero, else 0. */
+
+static const unsigned char BitLengthTable[32] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+};
+
+static int
+bits_in_digit(digit d)
+{
+ int d_bits = 0;
+ while (d >= 32) {
+ d_bits += 6;
+ d >>= 6;
+ }
+ d_bits += (int)BitLengthTable[d];
+ return d_bits;
+}
+
size_t
_PyLong_NumBits(PyObject *vv)
{
PyLongObject *v = (PyLongObject *)vv;
size_t result = 0;
Py_ssize_t ndigits;
+ int msd_bits;
assert(v != NULL);
assert(PyLong_Check(v));
@@ -725,12 +745,10 @@ _PyLong_NumBits(PyObject *vv)
if ((size_t)(ndigits - 1) > SIZE_MAX / (size_t)PyLong_SHIFT)
goto Overflow;
result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT;
- do {
- ++result;
- if (result == 0)
- goto Overflow;
- msd >>= 1;
- } while (msd);
+ msd_bits = bits_in_digit(msd);
+ if (SIZE_MAX - msd_bits < result)
+ goto Overflow;
+ result += msd_bits;
}
return result;
@@ -1102,7 +1120,6 @@ PyLong_FromUnsignedLongLong(unsigned long long ival)
v = _PyLong_New(ndigits);
if (v != NULL) {
digit *p = v->ob_digit;
- Py_SIZE(v) = ndigits;
while (ival) {
*p++ = (digit)(ival & PyLong_MASK);
ival >>= PyLong_SHIFT;
@@ -1416,26 +1433,6 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)
Py_RETURN_NOTIMPLEMENTED; \
} while(0)
-/* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d <
- 2**k if d is nonzero, else 0. */
-
-static const unsigned char BitLengthTable[32] = {
- 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-};
-
-static int
-bits_in_digit(digit d)
-{
- int d_bits = 0;
- while (d >= 32) {
- d_bits += 6;
- d >>= 6;
- }
- d_bits += (int)BitLengthTable[d];
- return d_bits;
-}
-
/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n]
* is modified in place, by adding y to it. Carries are propagated as far as
* x[m-1], and the remaining carry (0 or 1) is returned.
@@ -2482,7 +2479,7 @@ _PyLong_FromBytes(const char *s, Py_ssize_t len, int base)
PyObject *
PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
{
- PyObject *v, *unicode = PyUnicode_FromUnicode(u, length);
+ PyObject *v, *unicode = PyUnicode_FromWideChar(u, length);
if (unicode == NULL)
return NULL;
v = PyLong_FromUnicodeObject(unicode, base);
@@ -2494,7 +2491,8 @@ PyObject *
PyLong_FromUnicodeObject(PyObject *u, int base)
{
PyObject *result, *asciidig;
- char *buffer, *end = NULL;
+ const char *buffer;
+ char *end = NULL;
Py_ssize_t buflen;
asciidig = _PyUnicode_TransformDecimalAndSpaceToASCII(u);
@@ -3105,9 +3103,7 @@ long_add(PyLongObject *a, PyLongObject *b)
CHECK_BINOP(a, b);
if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) {
- PyObject *result = PyLong_FromLong(MEDIUM_VALUE(a) +
- MEDIUM_VALUE(b));
- return result;
+ return PyLong_FromLong(MEDIUM_VALUE(a) + MEDIUM_VALUE(b));
}
if (Py_SIZE(a) < 0) {
if (Py_SIZE(b) < 0) {
@@ -3141,9 +3137,7 @@ long_sub(PyLongObject *a, PyLongObject *b)
CHECK_BINOP(a, b);
if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) {
- PyObject* r;
- r = PyLong_FromLong(MEDIUM_VALUE(a)-MEDIUM_VALUE(b));
- return r;
+ return PyLong_FromLong(MEDIUM_VALUE(a) - MEDIUM_VALUE(b));
}
if (Py_SIZE(a) < 0) {
if (Py_SIZE(b) < 0)
@@ -4296,22 +4290,22 @@ long_rshift(PyLongObject *a, PyLongObject *b)
PyLongObject *a1, *a2;
a1 = (PyLongObject *) long_invert(a);
if (a1 == NULL)
- goto rshift_error;
+ return NULL;
a2 = (PyLongObject *) long_rshift(a1, b);
Py_DECREF(a1);
if (a2 == NULL)
- goto rshift_error;
+ return NULL;
z = (PyLongObject *) long_invert(a2);
Py_DECREF(a2);
}
else {
shiftby = PyLong_AsSsize_t((PyObject *)b);
if (shiftby == -1L && PyErr_Occurred())
- goto rshift_error;
+ return NULL;
if (shiftby < 0) {
PyErr_SetString(PyExc_ValueError,
"negative shift count");
- goto rshift_error;
+ return NULL;
}
wordshift = shiftby / PyLong_SHIFT;
newsize = Py_ABS(Py_SIZE(a)) - wordshift;
@@ -4323,19 +4317,15 @@ long_rshift(PyLongObject *a, PyLongObject *b)
himask = PyLong_MASK ^ lomask;
z = _PyLong_New(newsize);
if (z == NULL)
- goto rshift_error;
- if (Py_SIZE(a) < 0)
- Py_SIZE(z) = -(Py_SIZE(z));
+ return NULL;
for (i = 0, j = wordshift; i < newsize; i++, j++) {
z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
if (i+1 < newsize)
z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask;
}
- z = long_normalize(z);
+ z = maybe_small_long(long_normalize(z));
}
- rshift_error:
- return (PyObject *) maybe_small_long(z);
-
+ return (PyObject *)z;
}
static PyObject *
@@ -5089,7 +5079,8 @@ static PyObject *
long_bit_length(PyLongObject *v)
{
PyLongObject *result, *x, *y;
- Py_ssize_t ndigits, msd_bits = 0;
+ Py_ssize_t ndigits;
+ int msd_bits;
digit msd;
assert(v != NULL);
@@ -5100,11 +5091,7 @@ long_bit_length(PyLongObject *v)
return PyLong_FromLong(0);
msd = v->ob_digit[ndigits-1];
- while (msd >= 32) {
- msd_bits += 6;
- msd >>= 6;
- }
- msd_bits += (long)(BitLengthTable[msd]);
+ msd_bits = bits_in_digit(msd);
if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT)
return PyLong_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits);