Commit 8accd6b3 authored by Mark Dickinson's avatar Mark Dickinson

Revert accidental changes to Objects/longobject.c

parent 2e72b0d6
...@@ -1775,9 +1775,9 @@ _PyLong_Format(PyObject *aa, int base) ...@@ -1775,9 +1775,9 @@ _PyLong_Format(PyObject *aa, int base)
Py_ssize_t i, sz; Py_ssize_t i, sz;
Py_ssize_t size_a; Py_ssize_t size_a;
Py_UNICODE *p; Py_UNICODE *p;
int bits, negative; int bits;
char sign = '\0';
assert(base == 2 || base == 8 || base == 10 || base == 16);
if (base == 10) if (base == 10)
return long_to_decimal_string((PyObject *)a); return long_to_decimal_string((PyObject *)a);
...@@ -1785,34 +1785,23 @@ _PyLong_Format(PyObject *aa, int base) ...@@ -1785,34 +1785,23 @@ _PyLong_Format(PyObject *aa, int base)
PyErr_BadInternalCall(); PyErr_BadInternalCall();
return NULL; return NULL;
} }
assert(base >= 2 && base <= 36);
size_a = ABS(Py_SIZE(a)); size_a = ABS(Py_SIZE(a));
negative = Py_SIZE(a) < 0;
/* Compute a rough upper bound for the length of the string */ /* Compute a rough upper bound for the length of the string */
switch (base) { i = base;
case 2: bits = 0;
bits = 1; while (i > 1) {
break; ++bits;
case 8: i >>= 1;
bits = 3;
break;
case 16:
bits = 4;
break;
default:
assert(0); /* never get here */
} }
/* length of string required: +1 for negative sign, +2 for prefix */
i = 5; i = 5;
/* ensure we don't get signed overflow in sz calculation */ /* ensure we don't get signed overflow in sz calculation */
if (size_a > (PY_SSIZE_T_MAX - 4) / PyLong_SHIFT) { if (size_a > (PY_SSIZE_T_MAX - i) / PyLong_SHIFT) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
"int is too large to format"); "int is too large to format");
return NULL; return NULL;
} }
sz = 3 + negative + (size_a * PyLong_SHIFT - 1) / bits;
sz = i + 1 + (size_a * PyLong_SHIFT - 1) / bits; sz = i + 1 + (size_a * PyLong_SHIFT - 1) / bits;
assert(sz >= 0); assert(sz >= 0);
str = PyUnicode_FromUnicode(NULL, sz); str = PyUnicode_FromUnicode(NULL, sz);
...@@ -1820,11 +1809,13 @@ _PyLong_Format(PyObject *aa, int base) ...@@ -1820,11 +1809,13 @@ _PyLong_Format(PyObject *aa, int base)
return NULL; return NULL;
p = PyUnicode_AS_UNICODE(str) + sz; p = PyUnicode_AS_UNICODE(str) + sz;
*p = '\0'; *p = '\0';
if (Py_SIZE(a) < 0)
sign = '-';
if (Py_SIZE(a) == 0) { if (Py_SIZE(a) == 0) {
*--p = '0'; *--p = '0';
} }
assert((base & (base-1)) = 0); else if ((base & (base - 1)) == 0) {
/* JRH: special case for power-of-2 bases */ /* JRH: special case for power-of-2 bases */
twodigits accum = 0; twodigits accum = 0;
int accumbits = 0; /* # of bits in accum */ int accumbits = 0; /* # of bits in accum */
...@@ -1847,14 +1838,83 @@ _PyLong_Format(PyObject *aa, int base) ...@@ -1847,14 +1838,83 @@ _PyLong_Format(PyObject *aa, int base)
} while (i < size_a-1 ? accumbits >= basebits : } while (i < size_a-1 ? accumbits >= basebits :
accum > 0); accum > 0);
} }
}
else {
/* Not 0, and base not a power of 2. Divide repeatedly by
base, but for speed use the highest power of base that
fits in a digit. */
Py_ssize_t size = size_a;
digit *pin = a->ob_digit;
PyLongObject *scratch;
/* powbasw <- largest power of base that fits in a digit. */
digit powbase = base; /* powbase == base ** power */
int power = 1;
for (;;) {
twodigits newpow = powbase * (twodigits)base;
if (newpow >> PyLong_SHIFT)
/* doesn't fit in a digit */
break;
powbase = (digit)newpow;
++power;
}
/* Get a scratch area for repeated division. */
scratch = _PyLong_New(size);
if (scratch == NULL) {
Py_DECREF(str);
return NULL;
}
if (base == 16) /* Repeatedly divide by powbase. */
do {
int ntostore = power;
digit rem = inplace_divrem1(scratch->ob_digit,
pin, size, powbase);
pin = scratch->ob_digit; /* no need to use a again */
if (pin[size - 1] == 0)
--size;
SIGCHECK({
Py_DECREF(scratch);
Py_DECREF(str);
return NULL;
})
/* Break rem into digits. */
assert(ntostore > 0);
do {
digit nextrem = (digit)(rem / base);
char c = (char)(rem - nextrem * base);
assert(p > PyUnicode_AS_UNICODE(str));
c += (c < 10) ? '0' : 'a'-10;
*--p = c;
rem = nextrem;
--ntostore;
/* Termination is a bit delicate: must not
store leading zeroes, so must get out if
remaining quotient and rem are both 0. */
} while (ntostore && (size || rem));
} while (size != 0);
Py_DECREF(scratch);
}
if (base == 16) {
*--p = 'x'; *--p = 'x';
else if (base == 8) *--p = '0';
}
else if (base == 8) {
*--p = 'o'; *--p = 'o';
else /* base == 2 */ *--p = '0';
}
else if (base == 2) {
*--p = 'b'; *--p = 'b';
*--p = '0'; *--p = '0';
}
else if (base != 10) {
*--p = '#';
*--p = '0' + base%10;
if (base > 10)
*--p = '0' + base/10;
}
if (sign) if (sign)
*--p = sign; *--p = sign;
if (p != PyUnicode_AS_UNICODE(str)) { if (p != PyUnicode_AS_UNICODE(str)) {
......
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