Skip to the content.
def generate_bitmask(bits,base_bits):
    base = 1 << base_bits
    num = 0
    bits_in_block = base_bits << 1
    for i in range(bits//bits_in_block):
        num = (num << bits_in_block) | (base - 1)
    return num
   
def generate_all_bitmask(bits):
    bitmask = []
    base_bits = 1
    while(base_bits < bits):
        bitmask.append(generate_bitmask(bits,base_bits))
        base_bits = base_bits << 1
    return bitmask 

def pop_count(n,bitmask,bits,base_bits):
    if(bits == base_bits):
        return n

    even_bits = n & bitmask[0]
    odd_bits = (n >> base_bits) & bitmask[0]
    sum_bits = odd_bits + even_bits

    return pop_count(sum_bits,bitmask[1:],bits,base_bits << 1)

def count_set_bits_naive(n):
    i = 0
    while(n):
        i += n & 1
        n = n >> 1
    return i
 
def count_set_bits_karnighan(n):
    i = 0
    while(n):
        n &= (n - 1)
        i += 1
    return i
       
def count_set_bits(numbers,method):
    sum_bits = []
    for i in numbers:
        sum_bits.append(method(i))
    return sum_bits 
 
def count_set_bits_pop_count(numbers,bits):
    bitmask = generate_all_bitmask(bits)
    sum_bits = []
    for n in numbers:
        sum_bits.append(pop_count(n,bitmask,bits,1))
    return sum_bits

numbers = range(1<<21)

print(count_set_bits_pop_count(numbers,32) == count_set_bits(numbers,count_set_bits_karnighan) == count_set_bits(numbers,count_set_bits_naive))