417просмотров
16 ноября 2025 г.
questionScore: 459
Как подсчитать число выставленных битов (единиц) в целом беззнаковом?
Давайте возьмем C++ 20, где в <bit> появилась функция std::popcount, которая делает, то что нам нужно:
#include <iostream>
#include <bit>
#include <cstdint> int main() { uint8_t u1 = 0b00011101; unsigned u2 = 123; // 0b1111011 std::cout << std::popcount(u1) << " " << std::popcount(u2) << std::endl; // 4 6 return 0;
} Скучно? На первый взгляд да, но в C++ всегда можно закопаться в детали =)
Во-первых, что за странное название? Почему не какой-нибудь bit_set_count?
Оказывается, что popcount это сокращение от “population count”.
Вроде немного понятнее, но лучше не стало) Чтож, почитаем хабр: https://habr.com/ru/articles/467083/
Кроме пространного списка задач, где для решения используется эта функция, из статьи мы узнаём
что во многих процессорах есть специальная инструкция (н-р POPCNT на X86), которая выполняет
данное вычисление очень быстро (за такт?). Кроме того, в GCC и CLANG есть встроенные функции, которые также вычисляют popcount очень быстро и что-то мне подсказывает, что они могут вызывать эту единственную инструкцию (а может и нет). В GCC эта функция наз-ся __builtin_popcount. Пример можно посмотреть тут: https://godbolt.org/z/84ETrhfnK
Как видим, в дебаге GCC вставит встроенную __popcountdi2 функцию, а для std::popcount будет другая.
Если же добавить -O3, то разницы не будет никакой.
Замеры делать не буду)