mirror of
https://github.com/python/cpython.git
synced 2025-08-03 00:23:06 +00:00
Added new private API function _PyLong_NumBits. This will be used at the
start for the C implemention of new pickle LONG1 and LONG4 opcodes (the linear-time way to pickle a long is to call _PyLong_AsByteArray, but the caller has no idea how big an array to allocate, and correct calculation is a bit subtle).
This commit is contained in:
parent
3d8c01b31c
commit
baefd9e552
3 changed files with 85 additions and 2 deletions
|
@ -260,6 +260,41 @@ PyLong_AsUnsignedLong(PyObject *vv)
|
|||
return x;
|
||||
}
|
||||
|
||||
size_t
|
||||
_PyLong_NumBits(PyObject *vv)
|
||||
{
|
||||
PyLongObject *v = (PyLongObject *)vv;
|
||||
size_t result = 1; /* for the sign bit */
|
||||
size_t ndigits = ABS(v->ob_size);
|
||||
|
||||
assert(v != NULL);
|
||||
assert(PyLong_Check(v));
|
||||
assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
|
||||
if (ndigits > 0) {
|
||||
size_t product;
|
||||
digit msd = v->ob_digit[ndigits - 1];
|
||||
|
||||
product = (ndigits - 1) * SHIFT;
|
||||
if (product / SHIFT != ndigits - 1)
|
||||
goto Overflow;
|
||||
result += product;
|
||||
if (result < product)
|
||||
goto Overflow;
|
||||
do {
|
||||
++result;
|
||||
if (result == 0)
|
||||
goto Overflow;
|
||||
msd >>= 1;
|
||||
} while (msd);
|
||||
}
|
||||
return result;
|
||||
|
||||
Overflow:
|
||||
PyErr_SetString(PyExc_OverflowError, "long has too many bits "
|
||||
"to express in a platform size_t");
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
_PyLong_FromByteArray(const unsigned char* bytes, size_t n,
|
||||
int little_endian, int is_signed)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue