summaryrefslogtreecommitdiffstats
path: root/Objects/longobject.c
diff options
context:
space:
mode:
authorNiklas Fiekas <niklas.fiekas@backscattering.de>2020-01-16 14:09:19 (GMT)
committerVictor Stinner <vstinner@python.org>2020-01-16 14:09:19 (GMT)
commitc5b79003f5fe6aa28a2a028680367839ba8677db (patch)
treeef8be6cb5538ff0bf96478f6feed362a71d95dc2 /Objects/longobject.c
parent4691a2f2a2b8174a6c958ce6976ed5f3354c9504 (diff)
downloadcpython-c5b79003f5fe6aa28a2a028680367839ba8677db.zip
cpython-c5b79003f5fe6aa28a2a028680367839ba8677db.tar.gz
cpython-c5b79003f5fe6aa28a2a028680367839ba8677db.tar.bz2
bpo-31031: Unify duplicate bits_in_digit and bit_length (GH-2866)
Add _Py_bit_length() to unify duplicate bits_in_digit() and bit_length().
Diffstat (limited to 'Objects/longobject.c')
-rw-r--r--Objects/longobject.c38
1 files changed, 9 insertions, 29 deletions
diff --git a/Objects/longobject.c b/Objects/longobject.c
index be9301f..b672ae4 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -803,26 +803,6 @@ _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)
{
@@ -840,7 +820,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 = bits_in_digit(msd);
+ msd_bits = _Py_bit_length(msd);
if (SIZE_MAX - msd_bits < result)
goto Overflow;
result += msd_bits;
@@ -1950,7 +1930,7 @@ long_format_binary(PyObject *aa, int base, int alternate,
return -1;
}
size_a_in_bits = (size_a - 1) * PyLong_SHIFT +
- bits_in_digit(a->ob_digit[size_a - 1]);
+ _Py_bit_length(a->ob_digit[size_a - 1]);
/* Allow 1 character for a '-' sign. */
sz = negative + (size_a_in_bits + (bits - 1)) / bits;
}
@@ -2770,7 +2750,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 - bits_in_digit(w1->ob_digit[size_w-1]);
+ d = PyLong_SHIFT - _Py_bit_length(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);
@@ -2891,7 +2871,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e)
*e = 0;
return 0.0;
}
- a_bits = bits_in_digit(a->ob_digit[a_size-1]);
+ a_bits = _Py_bit_length(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 &&
@@ -3986,8 +3966,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 + bits_in_digit(a->ob_digit[a_size - 1]) -
- bits_in_digit(b->ob_digit[b_size - 1]);
+ diff = diff * PyLong_SHIFT + _Py_bit_length(a->ob_digit[a_size - 1]) -
+ _Py_bit_length(b->ob_digit[b_size - 1]);
/* Now diff = a_bits - b_bits. */
if (diff > DBL_MAX_EXP)
goto overflow;
@@ -4063,7 +4043,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+bits_in_digit(x->ob_digit[x_size-1]);
+ x_bits = (x_size-1)*PyLong_SHIFT+_Py_bit_length(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;
@@ -4877,7 +4857,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 = bits_in_digit(a->ob_digit[size_a-1]);
+ nbits = _Py_bit_length(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);
@@ -5395,7 +5375,7 @@ int_bit_length_impl(PyObject *self)
return PyLong_FromLong(0);
msd = ((PyLongObject *)self)->ob_digit[ndigits-1];
- msd_bits = bits_in_digit(msd);
+ msd_bits = _Py_bit_length(msd);
if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT)
return PyLong_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits);