題目描述:
int even_ones(unsigned x);
函數應該遵循位級整數編碼規則,不過你可以假設資料類型int 有w=32位。
你的代碼最多隻能包含12個算術運算、位運算和邏輯運算。
代碼如下:
bool OddOnes(int x)
{
x = x ^ (x >> 1);
x = x ^ (x >> 2);
x = x ^ (x >> 4);
x = x ^ (x >> 8);
x = x ^ (x >> 16);
return !(x & 1);
}
分析:
我在這裡引用網友Matrix67的部分分析:
為了說明上面這段代碼的原理,我們拿1314520出來說事。1314520的二進制為101000000111011011000,第一次異或操作的結果如下:
00000000000101000000111011011000
XOR 0000000000010100000011101101100
---------------------------------------
00000000000111100000100110110100
得到的結果是一個新的二進制數,其中右起第i位上的數表示原數中第i和i+1位上有奇數個1還是偶數個1。比如,最右邊那個0表示原數末兩位有偶數個1,右起第3位上的1就表示原數的這個位置和前一個位置中有奇數個1。對這個數進行第二次異或的結果如下:
00000000000111100000100110110100
XOR 000000000001111000001001101101
---------------------------------------
00000000000110011000101111011001
結果裡的每個1表示原數的該位置及其前面三個位置中共有奇數個1,每個0就表示原數對應的四個位置上共偶數個1。一直做到第五次異或結束後,得到的二進制數的最末位就表示整個32位數裡有多少個1,這就是我們最終想要的答案。
相信很多網友還是沒有看明白怎麼回事,其實以上部分的形式化表示如下:
加上X的表示為x31....x0則:
第一次異或:x = x ^ (x >> 1);
x:

x>>1:
x ^ (x >> 1):
第二次異或:x = x ^ (x >> 2);
x:
x >> 2:
x ^ (x >> 2):
第三次異或:x ^ (x >> 4)
x:
x >> 4:
x ^ (x >> 4):
第四次異或:x = x ^ (x >> 8)
x:
x >> 4:
x ^ (x >> 4):
第五次異或:x = x ^ (x >> 16)
x:
x >> 16:
x ^ (x >> 16)
從以上過程可以看出:在經過了五次異或之後,最後一位二進制值确實表示了整個二進制字元串中1出現個數的奇偶性。
參考部落格:http://www.matrix67.com/blog/archives/264