Proofs: Kernighan's bit count
These are the human proofs of Kernighan's bit count, at full length.
Kernighan's loop returns the number of 1-bits and runs once per 1-bit full
This proof shows: correctness, termination.
Fix . A word is an integer with , with bits such that . Let .
Lemma. For each word , the value is a word, and . More exactly, it is with its lowest 1-bit cleared.
Proof. Since , has a lowest 1-bit; call its position . So and for . Then with , and is a multiple of . Since , is a word with no wrap-around. Its bits are: for (from ), 0 at position , and 1 at each position . The AND of and has bit at each , bit at , and bit at each . So , which is with bit cleared, and .
Theorem. For each word , KERNIGHAN-POPCOUNT stops after exactly iterations of the loop and returns .
Proof. We use this invariant of the loop of line L2.
(I) is a word, , and . Also, equals the number of iterations done so far.
Initialization. Before the first test, line L1 gives and , so (I) holds.
Maintenance. Assume (I) and that the test of line L2 is true, so . By the lemma, line L3 makes a word with one smaller. Line L4 makes one larger, and one more iteration is done. So does not change, and (I) holds again.
Termination. By (I), , and each iteration raises by exactly 1. Since , at most iterations can run. While we have and the loop goes on, and holds exactly when . So the loop stops exactly when , after iterations. Line L5 returns .
Remark on signed words. The lemma needs to be computed without overflow. For an unsigned word this holds. In a signed -bit type, gives , which is outside the range; in C this is undefined behaviour. In arithmetic modulo the lemma applies to the bit pattern, which is why the algorithm is stated for unsigned words.