int ce_bin_wei() { //unsigned int a=1999,b=2299; int a=1999,b=2299; int i=0; int sum=0; for(i=0;i<31;i++) { sum+=(a&1)^(b&1); a>>=1; b>>=1; //a/=2; //b/=2; } return sum; }
================================== //方法二
#include <stdio.h> int count_one(int num) { int count = 0; while (num) { count++; num = num&(num - 1);//將二進制中從最低位出現的首個1變成零 } return count; } int main() { int n1 = 0; int n2 = 0; scanf("%d%d", &n1, &n2); int num = n1^n2; int ret = count_one(num); printf("%d\n", ret); system("pause"); return 0; }
2.編寫函數: 1 unsigned int reverse_bit(unsigned int value); 這個函數的返回 值value的二進制位模式從左到右翻轉後的值。 如: 在32位機器上25這個值包含下列各位: 00000000000000000000000000011001 翻轉後:(2550136832) 10011000000000000000000000000000 程序結果返回: 2550136832
unsigned int reverse_bit(unsigned int value) { unsigned int rev_val=0; int i=0; for(i=0;i<32;i++) { rev_val<<=1; rev_val+=(value&1); value>>=1; } return rev_val; }
============================================= 另外一種
typedef unsigned int uint; uint reverse_bit(uint value) { int i = 0; uint sum = 0; for (i = 0; i < 32; i++) { sum += ((value >> i) & 1)*pow(2, 31 - i); } return sum; }
============================================== 3.不使用(a+b)/2這種方式,求兩個數的平均值。
#include <stdio.h> int main() { int num1 = 10; int num2 = 20; int avg = num1&num2 + (num1^num2) >> 1; //方法1 num1&num2
//①先說相同位====== num1與num2二進制中 同一的保留下來形成兩個相等的數a1 a2 這兩個相等的數相加除以2 等於自己本 身 //也就是 num1&num2 (如 num1=(1)十進制=(0001)這裡簡單表示,沒有寫全32位 num2=(3)十進制=(0011)二進制 ) // num1&num2=0001 (0001=(0001(num1中與num2相等的)+0001)/2) //②再說不同位====== (num1^num2) 兩數不同位異或 (不會產生溢出 ) 右移一位 相當於除二 //以上兩步都不會產生溢出 //方法二 這種好理解 同樣也沒有溢出
//=====================int avg2 = num1 - (num1 - num2) / 2;=================== printf("%d\n", avg); system("pause"); return 0; }
4.一組數據中只有一個數字出現了一次。 其他所有數字都是成對出現的。請找出這個數字。(使用位運算)
int find_d(int arr[],int len) { int i=0; int temp=0; for(i=0;i<len;i++) { temp^=arr[i]; } return temp; }
//==================相同兩數異或 結果為0 ===============一群數字亦或 相當於消去其中相同的 最終結果為其中不同的數字異或的結果 5、【加強版】 一個整型數組裡除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。 [異或運算的性質:任何一個數字異或它自己都等於0 ] [有了上面簡單問題4的解決方案之後,我們回到原始的問題。如果能夠把原數組分為兩個子數組。在每個子數組中,包含一個只 出現一次的數字,而其他數字都出現兩次。如果能夠這樣拆分原數組,按照前面的辦法就是分別求出這兩個只出現一次的數字了 。 我們還是從頭到尾依次異或數組中的每一個數字,那麼最終得到的結果就是兩個只出現一次的數字的異或結果。因為其他數字都 出現了兩次,在異或中全部抵消掉了。由於這兩個數字肯定不一樣,那麼這個異或結果肯定不為0,也就是說在這個結果數字的 二進制表示中至少就有一位為1。我們在結果數字中找到第一個為1的位的位置,記為第N位。現在我們以第N位是不是1為標准把 原數組中的數字分成兩個子數組,第一個子數組中每個數字的第N位都為1,而第二個子數組的每個數字的第N位都為0。(這兩個 數字不同,意味著為1的那個位是相異的) ]
#include <stdio.h> //#include <stdlib.h> int main() { int arr[] = {2,2,3,3,-1,5}; int i = 0; int result = 0; int num1=0; int num2=0; int count=0; int len=sizeof(arr) / sizeof(arr[0]); for (i = 0; i < len; i++) { result^= arr[i]; //異或結束相當於兩個數異或的結果 } //找出這兩個數的第一個相異位置 count=1; i=1; while(result){ if((result&i)==1) { break; } result>>=1; count<<=1; } //按照這個位置把數組分成兩組 num1 = 0; num2 = 0; for(i=0;i<len;i++) { if((arr[i]&count)==0) { num1 ^= arr[i]; }else{ num2 ^= arr[i]; } } printf("%d %d\n", num1,num2); //system("pause"); return 0; }