題目描述:
/* Return 1 when x contains an even number of 1s;0 otherwise. Assume W=32 */
int even_ones(unsigned x);
函數應該遵循位級整數編碼規則,不過你可以假設數據類型int 有w=32位。
你的代碼最多只能包含12個算術運算、位運算和邏輯運算。
代碼如下:
1 int even_ones(unsigned x) 2 { 3 x = x ^ (x >> 1); 4 x = x ^ (x >> 2); 5 x = x ^ (x >> 4); 6 x = x ^ (x >> 8); 7 x = x ^ (x >> 16); 8 return !(x & 1); 9 }
代碼分析:
我們首先用一個具體的數據來測試這段代碼,比如我們用444164這個數字,444164的二進制為1101100011100000100.
第一次異或操作:
00000000000001101100011100000100
^
00000000000000110110001110000010
=
00000000000001011010010010000110
關於得出的這個結果,我們認為右起的第i位,表示原數第i位和第i+1位中包含1的奇偶情況。比如右起第0位為0,則原數第0和第1位包含1的個數為偶;而右起第1位為1,則原數第1位和第2位包含1的個數為奇。。。
為什么可以得出這個結論呢?x >> 1,我們假設這個數為x',而x'的第i位數實際上就是x的第i+1位,所以x ^ x',實際就是x的第i位與第i+1位異或,而異或的定義為相同為0,不同為1,所以如果這兩位都為1或都為0,包含偶數個1,則結果為0,反之亦然。
第二次異或操作:
00000000000001011010010010000110
^
00000000000000010110100100100001
=
00000000000001001100010110100111
關於得出的這個結果,我們認為右起的第i位,表示原數第i位和第i+1,i+2,i+3位中包含1的奇偶情況。為什么能得出這樣的結論?我們先看第一次操作的結果,第0位表示原數的第0和第1位的情況,第1位表示原數第1位和第2位的情況,第2位表示原數第2位和第3位的情況。。。我們假設第2次異或操作的數為x2,而x2 >> 2 的結果為 x2',這時,x2'的第0位其實是x2的第2位,所以x2 ^ x2' 實際上是x2的第i位和第i+2位的異或,而我們前面提到 第0位表示原數的第0和第1位的情況,第2位表示原數第2位和第3位的情況,所以第二次操作得出的結果的第i位是 x2的第i位和第i+2位的異或,即表示原數第i位和第i+1,i+2,i+3位中包含1的奇偶情況。
剩下的幾次異或操作分析很上面類似。。。
整個操作的形式化表示如下:
1.x ^ (x >> 1)
x:
x >> 1:
x ^ (x >> 1):
2.x ^ (x >> 2)
x:
x >> 2:
x ^ (x >> 2):
3.x ^ (x >> 4)
x:
x >> 4:
x ^ (x >> 4):
4.x ^ (x >> 8)
x:
x >> 8:
x ^ (x >> 8):
5.x ^ (x >> 16)
x:
x >> 16:
x ^ (x >> 16):
參考博客:http://www.matrix67.com/blog/archives/264