劍指OFFER上的一道原題,鑽了個牛角尖
求二進制中1的個數
問題出現在負數,因為要保持負數的性質,所以對負數進行右移操作后將在首位重新補1,若干次右移后將變為0xFFFFFFFF.
如果要去掉負數的符號位,可以考慮用:
int a=-127;
a=a^(0x80000000);
0x80000000就是32位中首位為1,而異或對於a的后31位來說,與0異或的結果仍未0,而對於首位,1與0異或將為0.
在這個基礎上右移得到的1的個數就是除首位1之外的1的個數。
最后對負數把首位的1個數補上即可。
實際上處理的時候完全可以通過對1左移的形式來獲得a中1的個數,完全不必要如此麻煩。
另外劍指offer中還有一個解法:
(n-1)&n;
假設對於n,其右側第一個不為0的位置為m,則n-1使m為0,m右側全為1。在將n-1與n進行&操作則將m及m右側全部置位0。
因此
while(n)
(n-1)&n;
將使n逐次消掉其右側的1