.. versionadded:: 3.1
+.. method:: int.bit_count()
+
+ Return the number of ones in the binary representation of the absolute
+ value of the integer. This is also known as the population count.
+ Example::
+
+ >>> n = 19
+ >>> bin(n)
+ '0b10011'
+ >>> n.bit_count()
+ 3
+ >>> (-n).bit_count()
+ 3
+
+ Equivalent to::
+
+ def bit_count(self):
+ return bin(self).count("1")
+
+ .. versionadded:: 3.10
+
.. method:: int.to_bytes(length, byteorder, \*, signed=False)
Return an array of bytes representing an integer.
New Features
============
+* The :class:`int` type has a new method :meth:`int.bit_count`, returning the
+ number of ones in the binary expansion of a given integer, also known
+ as the population count. (Contributed by Niklas Fiekas in :issue:`29882`.)
Other Language Changes
True
>>> real_tests = [t for t in tests if len(t.examples) > 0]
>>> len(real_tests) # objects that actually have doctests
- 13
+ 14
>>> for t in real_tests:
... print('{} {}'.format(len(t.examples), t.name))
...
1 builtins.hex
1 builtins.int
3 builtins.int.as_integer_ratio
+ 2 builtins.int.bit_count
2 builtins.int.bit_length
5 builtins.memoryview.hex
1 builtins.oct
self.assertEqual((a+1).bit_length(), i+1)
self.assertEqual((-a-1).bit_length(), i+1)
+ def test_bit_count(self):
+ for a in range(-1000, 1000):
+ self.assertEqual(a.bit_count(), bin(a).count("1"))
+
+ for exp in [10, 17, 63, 64, 65, 1009, 70234, 1234567]:
+ a = 2**exp
+ self.assertEqual(a.bit_count(), 1)
+ self.assertEqual((a - 1).bit_count(), exp)
+ self.assertEqual((a ^ 63).bit_count(), 7)
+ self.assertEqual(((a - 1) ^ 510).bit_count(), exp - 8)
+
def test_round(self):
# check round-half-even algorithm. For round to nearest ten;
# rounding map is invariant under adding multiples of 20
--- /dev/null
+Add :meth:`int.bit_count()`, counting the number of ones in the binary
+representation of an integer. Patch by Niklas Fiekas.
return int_bit_length_impl(self);
}
+PyDoc_STRVAR(int_bit_count__doc__,
+"bit_count($self, /)\n"
+"--\n"
+"\n"
+"Number of ones in the binary representation of the absolute value of self.\n"
+"\n"
+"Also known as the population count.\n"
+"\n"
+">>> bin(13)\n"
+"\'0b1101\'\n"
+">>> (13).bit_count()\n"
+"3");
+
+#define INT_BIT_COUNT_METHODDEF \
+ {"bit_count", (PyCFunction)int_bit_count, METH_NOARGS, int_bit_count__doc__},
+
+static PyObject *
+int_bit_count_impl(PyObject *self);
+
+static PyObject *
+int_bit_count(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ return int_bit_count_impl(self);
+}
+
PyDoc_STRVAR(int_as_integer_ratio__doc__,
"as_integer_ratio($self, /)\n"
"--\n"
exit:
return return_value;
}
-/*[clinic end generated code: output=63b8274fc784d617 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=4257cfdb155efd00 input=a9049054013a1b77]*/
return NULL;
}
+static int
+popcount_digit(digit d)
+{
+ /* 32bit SWAR popcount. */
+ uint32_t u = d;
+ u -= (u >> 1) & 0x55555555U;
+ u = (u & 0x33333333U) + ((u >> 2) & 0x33333333U);
+ u = (u + (u >> 4)) & 0x0f0f0f0fU;
+ return (uint32_t)(u * 0x01010101U) >> 24;
+}
+
+/*[clinic input]
+int.bit_count
+
+Number of ones in the binary representation of the absolute value of self.
+
+Also known as the population count.
+
+>>> bin(13)
+'0b1101'
+>>> (13).bit_count()
+3
+[clinic start generated code]*/
+
+static PyObject *
+int_bit_count_impl(PyObject *self)
+/*[clinic end generated code: output=2e571970daf1e5c3 input=7e0adef8e8ccdf2e]*/
+{
+ assert(self != NULL);
+ assert(PyLong_Check(self));
+
+ PyLongObject *z = (PyLongObject *)self;
+ Py_ssize_t ndigits = Py_ABS(Py_SIZE(z));
+ Py_ssize_t bit_count = 0;
+
+ /* Each digit has up to PyLong_SHIFT ones, so the accumulated bit count
+ from the first PY_SSIZE_T_MAX/PyLong_SHIFT digits can't overflow a
+ Py_ssize_t. */
+ Py_ssize_t ndigits_fast = Py_MIN(ndigits, PY_SSIZE_T_MAX/PyLong_SHIFT);
+ for (Py_ssize_t i = 0; i < ndigits_fast; i++) {
+ bit_count += popcount_digit(z->ob_digit[i]);
+ }
+
+ PyObject *result = PyLong_FromSsize_t(bit_count);
+ if (result == NULL) {
+ return NULL;
+ }
+
+ /* Use Python integers if bit_count would overflow. */
+ for (Py_ssize_t i = ndigits_fast; i < ndigits; i++) {
+ PyObject *x = PyLong_FromLong(popcount_digit(z->ob_digit[i]));
+ if (x == NULL) {
+ goto error;
+ }
+ PyObject *y = long_add((PyLongObject *)result, (PyLongObject *)x);
+ Py_DECREF(x);
+ if (y == NULL) {
+ goto error;
+ }
+ Py_DECREF(result);
+ result = y;
+ }
+
+ return result;
+
+ error:
+ Py_DECREF(result);
+ return NULL;
+}
/*[clinic input]
int.as_integer_ratio
{"conjugate", long_long_meth, METH_NOARGS,
"Returns self, the complex conjugate of any int."},
INT_BIT_LENGTH_METHODDEF
+ INT_BIT_COUNT_METHODDEF
INT_TO_BYTES_METHODDEF
INT_FROM_BYTES_METHODDEF
INT_AS_INTEGER_RATIO_METHODDEF