-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-29782: Consolidate _Py_Bit_Length() #20739
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
281009c
65abb83
ce45ff2
6464ca6
0bd4265
fbaca66
436f68b
ac664bc
3279d17
525da3d
e487622
a338761
5a146f7
8e3ce66
86241f6
c7ccbe2
dfceaf2
fbf01ae
991622b
462d995
98fc7a8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -695,6 +695,13 @@ _PyLong_Sign(PyObject *vv) | |
return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1); | ||
} | ||
|
||
static int | ||
bit_length_digit(digit x) | ||
{ | ||
Py_BUILD_ASSERT(PyLong_SHIFT <= sizeof(unsigned long) * 8); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice if C provided some standard way to get the width (in the sense of C99 §6.2.6.2p6) of an integer type, so that we didn't have to use |
||
return _Py_bit_length((unsigned long)x); | ||
} | ||
|
||
size_t | ||
_PyLong_NumBits(PyObject *vv) | ||
{ | ||
|
@@ -712,7 +719,7 @@ _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; | ||
msd_bits = _Py_bit_length(msd); | ||
msd_bits = bit_length_digit(msd); | ||
if (SIZE_MAX - msd_bits < result) | ||
goto Overflow; | ||
result += msd_bits; | ||
|
@@ -1822,7 +1829,7 @@ long_format_binary(PyObject *aa, int base, int alternate, | |
return -1; | ||
} | ||
size_a_in_bits = (size_a - 1) * PyLong_SHIFT + | ||
_Py_bit_length(a->ob_digit[size_a - 1]); | ||
bit_length_digit(a->ob_digit[size_a - 1]); | ||
/* Allow 1 character for a '-' sign. */ | ||
sz = negative + (size_a_in_bits + (bits - 1)) / bits; | ||
} | ||
|
@@ -2642,7 +2649,7 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) | |
|
||
/* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2. | ||
shift v1 left by the same amount. Results go into w and v. */ | ||
d = PyLong_SHIFT - _Py_bit_length(w1->ob_digit[size_w-1]); | ||
d = PyLong_SHIFT - bit_length_digit(w1->ob_digit[size_w-1]); | ||
carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d); | ||
assert(carry == 0); | ||
carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d); | ||
|
@@ -2764,7 +2771,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) | |
*e = 0; | ||
return 0.0; | ||
} | ||
a_bits = _Py_bit_length(a->ob_digit[a_size-1]); | ||
a_bits = bit_length_digit(a->ob_digit[a_size-1]); | ||
/* The following is an overflow-free version of the check | ||
"if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */ | ||
if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 && | ||
|
@@ -3857,8 +3864,8 @@ long_true_divide(PyObject *v, PyObject *w) | |
/* Extreme underflow */ | ||
goto underflow_or_zero; | ||
/* Next line is now safe from overflowing a Py_ssize_t */ | ||
diff = diff * PyLong_SHIFT + _Py_bit_length(a->ob_digit[a_size - 1]) - | ||
_Py_bit_length(b->ob_digit[b_size - 1]); | ||
diff = diff * PyLong_SHIFT + bit_length_digit(a->ob_digit[a_size - 1]) - | ||
bit_length_digit(b->ob_digit[b_size - 1]); | ||
/* Now diff = a_bits - b_bits. */ | ||
if (diff > DBL_MAX_EXP) | ||
goto overflow; | ||
|
@@ -3934,7 +3941,7 @@ long_true_divide(PyObject *v, PyObject *w) | |
} | ||
x_size = Py_ABS(Py_SIZE(x)); | ||
assert(x_size > 0); /* result of division is never zero */ | ||
x_bits = (x_size-1)*PyLong_SHIFT+_Py_bit_length(x->ob_digit[x_size-1]); | ||
x_bits = (x_size-1)*PyLong_SHIFT+bit_length_digit(x->ob_digit[x_size-1]); | ||
|
||
/* The number of extra bits that have to be rounded away. */ | ||
extra_bits = Py_MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; | ||
|
@@ -4748,7 +4755,7 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) | |
alloc_b = Py_SIZE(b); | ||
/* reduce until a fits into 2 digits */ | ||
while ((size_a = Py_SIZE(a)) > 2) { | ||
nbits = _Py_bit_length(a->ob_digit[size_a-1]); | ||
nbits = bit_length_digit(a->ob_digit[size_a-1]); | ||
/* extract top 2*PyLong_SHIFT bits of a into x, along with | ||
corresponding bits of b into y */ | ||
size_b = Py_SIZE(b); | ||
|
@@ -5269,7 +5276,7 @@ int_bit_length_impl(PyObject *self) | |
return PyLong_FromLong(0); | ||
|
||
msd = ((PyLongObject *)self)->ob_digit[ndigits-1]; | ||
msd_bits = _Py_bit_length(msd); | ||
msd_bits = bit_length_digit(msd); | ||
|
||
if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT) | ||
return PyLong_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits); | ||
|
Uh oh!
There was an error while loading. Please reload this page.