Я нигде не видел такого подхода:
int nbits(unsigned char v) {
return ((((v - ((v >> 1) & 0x55)) * 0x1010101) & 0x30c00c03) * 0x10040041) >> 0x1c;
}
Он работает на байт, поэтому его нужно будет вызывать 4 раза для 32-разрядного целого числа. Он получен из бокового сложения, но использует два 32-битных умножения, чтобы уменьшить количество команд до 7.
Большинство современных компиляторов C оптимизируют эту функцию, используя инструкции SIMD (SSE2), когда становится ясно, что число запросов кратно 4, и оно становится вполне конкурентоспособным. Он переносим, может быть определен как макрос или встроенная функция и не нуждается в таблицах данных.
Этот подход может быть расширен для работы с 16 битами одновременно с использованием 64-битных умножений. Однако происходит сбой, когда установлены все 16 битов, возвращая ноль, поэтому его можно использовать только при отсутствии входного значения 0xffff. Он также медленнее из-за 64-битных операций и плохо оптимизируется.