mirror of https://github.com/python/cpython
Issue #25402: in int-to-decimal-string conversion, reduce intermediate storage requirements and relax restriction on converting large integers. Patch by Serhiy Storchaka.
This commit is contained in:
parent
583c6e860c
commit
4e1de16f88
|
@ -10,6 +10,10 @@ What's New in Python 3.6.0 beta 1
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #25402: In int-to-decimal-string conversion, improve the estimate
|
||||||
|
of the intermediate memory required, and remove an unnecessarily strict
|
||||||
|
overflow check. Patch by Serhiy Storchaka.
|
||||||
|
|
||||||
- Issue #27214: In long_invert, be more careful about modifying object
|
- Issue #27214: In long_invert, be more careful about modifying object
|
||||||
returned by long_add, and remove an unnecessary check for small longs.
|
returned by long_add, and remove an unnecessary check for small longs.
|
||||||
Thanks Oren Milman for analysis and patch.
|
Thanks Oren Milman for analysis and patch.
|
||||||
|
|
|
@ -1591,6 +1591,7 @@ long_to_decimal_string_internal(PyObject *aa,
|
||||||
Py_ssize_t size, strlen, size_a, i, j;
|
Py_ssize_t size, strlen, size_a, i, j;
|
||||||
digit *pout, *pin, rem, tenpow;
|
digit *pout, *pin, rem, tenpow;
|
||||||
int negative;
|
int negative;
|
||||||
|
int d;
|
||||||
enum PyUnicode_Kind kind;
|
enum PyUnicode_Kind kind;
|
||||||
|
|
||||||
a = (PyLongObject *)aa;
|
a = (PyLongObject *)aa;
|
||||||
|
@ -1608,15 +1609,17 @@ long_to_decimal_string_internal(PyObject *aa,
|
||||||
|
|
||||||
But log2(a) < size_a * PyLong_SHIFT, and
|
But log2(a) < size_a * PyLong_SHIFT, and
|
||||||
log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT
|
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) {
|
d = (33 * _PyLong_DECIMAL_SHIFT) /
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
(10 * PyLong_SHIFT - 33 * _PyLong_DECIMAL_SHIFT);
|
||||||
"int too large to format");
|
assert(size_a < PY_SSIZE_T_MAX/2);
|
||||||
return -1;
|
size = 1 + size_a + size_a / d;
|
||||||
}
|
|
||||||
/* the expression size_a * PyLong_SHIFT is now safe from overflow */
|
|
||||||
size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT);
|
|
||||||
scratch = _PyLong_New(size);
|
scratch = _PyLong_New(size);
|
||||||
if (scratch == NULL)
|
if (scratch == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in New Issue