1、普通做法,每次除2取余位1則加1:
#include <stdio.h>int main(){ int num = 15; int count = 0; int i = 0; for (i = 0; i <= 32;i++)//while(num) { if (num % 2 == 1) { count++; } num = num / 2; } 正數的話問題,但是一個是效率比較差,一個是負數的時候有錯,而且可能會溢出(變成小數什么的)2、優化:可以使用向右移位代替除2運算:num=num>>1;(右移運算只是返回一個移位之后的值,但是移位的值本身不改變) 右移分邏輯一位位和算數移位。無符號數執行邏輯移位,右移一位,左邊補0;有符號數執行算數移位,右移一位,左邊補符號位(負數補1,正數補0)
但是負數還是有問題3、優化:使用按位與運算代替求模運算:if ((num&1)==1)
但是負數還是會有問題4、 對于負數來說,和正數會有不同的地方,例如-1的補碼: 原碼: 10000000 00000000 00000000 00000001 反碼: 11111111 11111111 11111111 11111110(符號位不變,其余按位取反) 補碼: 11111111 11111111 11111111 11111111(反碼加1) 這時候使用上邊的方法將達不到目的。。。
#include <stdio.h>int main(){ int num = -1; int count = 0; while (num) { count++; num = num&(num - 1); } printf("%d/n", count); return 0;}使用n&(n-1),這樣的話每次循環直接找到一個位位1的地方處理,相對于前面的方法來說,這個方法只需要循環二進制數中1的個數次,而不需要每一個數都運行32次,而且針對負數也能完美解決問題 來源: http://blog.csdn.net/Bulletproof_Circle/article/details/51242742
新聞熱點
疑難解答