Brian Kernighan’s Algorithm to Count the Set Bits of a Number

To count all set bits of a number, we can loop through all the bits and check whether any bit is set. For example, an integer has 32 bits. We can check all 32 bits in a loop to count the set (1) bits. Here will see how we can improve this mechanism using Brian Kernighan’s algorithm.

Brian Kernighan’s Algorithm

Before under standing this algorithm, we have understand a basic property of binary number.

If we subtract a number by 1, then all bits starting from the right most 1 will get altered.

For example, binary representation of 2392 is 100101011000. And binary representation of 2391 (2392 -1) is 100101010111.

Brian Kernighan's algorithm

From the above diagram, we can see that right most 1 is located at 3-rd bit position of 2392. An in 2391 (one less 2392) all right bits starting from the 3-rd position gets altered. This theory holds for any number.

Now if we do bitwise AND (&) operation between 2392 and 2391, the right most set bit (1) will become 0 in the result.

Removing right most 1

From the diagram above we can see that the right most 1 (at 3-rd bit position) becomes 0.

To generalize this behavior, we can say that the operation n & (n-1) removes one set bit from the result. If we do the same operation again with the result, then one more set bit would be removed. If we continue this as many times as the number of set bits, the result would become zero. So, the number of iterations is equal to the number of set bits.

So for an integer we don’t have to iterate 32 times, but as many times as the number of set bit.

C Implementation of Brian Kernighan’s Algorithm

#include <stdio.h>

int count_set_bits(unsigned int n) {
  int count = 0;
  while(n) {
    count++;
    n = n & (n-1);
  }
  
  return count;
}

void binary(unsigned int n)
{
    if(n > 0)
    {
        binary(n/2);
        printf("%d", n%2);
    }
}

void main()
{
    unsigned int num, result;

    printf("Enter an integer: ");
    scanf("%d", &num);

    printf("Binary of %d: ", num);
    binary(num);
    
    result = count_set_bits(num);
    
    printf("\nNumber of set bits in %d is %d.\n", num, result);
}

This program takes an integer as input and prints that in binary format. Then it counts the number of set bits by calling count_set_bits() function.

Here is the output.

Brian Kernighan's program output

Recursive Implementation

We can implement the same algorithm as recursive function also.

Logic

  1. If n is 0, return 0. There is no set bit in the input number n.
  2. If n & (n-1) is 0, then there is exactly on set bit in n. So return 1 in this case.
  3. If n & (n-1) is not 0, there are multiple set bits in n. So recursively get get the set bit count for n&(n-1). So the result would the the count from recursive call plus 1. Because at this stage exactly one set bit is cleared by n&(n-1) operation.

Here is the recursive version of count_set_bits() function.

int count_set_bits(unsigned int n) {
  unsigned int res;
  
  if (n == 0) return 0;
  
  res = n & (n-1);
  if (res == 0) return 1;
  
  return count_set_bits(res) + 1;
}

Author: Srikanta

I write here to help the readers learn and understand computer programing, algorithms, networking, OS concepts etc. in a simple way. I have 20 years of working experience in computer networking and industrial automation.


If you also want to contribute, click here.

Leave a Reply

Your email address will not be published. Required fields are marked *

0
1
0
1
4
0