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))