打印整數二進制的奇數位和偶數位
- 提取所有的奇數位,如果該位是1,輸出1,是0則輸出0
- 以同樣的方式提取偶數位置
#include<stdio.h>
#include<windows.h>
#pragma warning(disable:4996)
void Printf(int a)
{
int i = 0;
for (i = 30; i >= 0;i-=2)//奇數位
{
if(a&(1 << i))
{
printf("1 ");
}
else
{
printf("0 ");
}
}
printf("\n");
for (i = 31; i > 0; i -= 2)//偶數位
{
printf("%d ", (a>>i)&1 );
}
printf("\n");
}
int main()
{
int a=123;
Printf(a);
system("pause");
return 0;
}
123 的二進制序列
a=0000 0000 0000 0000 0000 0000 0111 1011
0000 0000 0000 0000 0000 0000 0000 0001
打印最高位偶數位將 實則將a 移動31 之後的偶數位依次減二
打印最高位奇數位將 實則將a 移動30 之後的奇數位依次減二
第一種做法
printf("%d ", (a>>i)&1 );
將a 移動對應的i 位 與1 進行按位與 按照%d 打印就可以,因爲按位與出來的結果前31 位全是0 最後一位不是 0 就是1 ,可以用十進制的格式打印。
如果將1 進行對應的移位操作,printf("%d ", a&(1<<i )); 並且還按照十進制格式輸出
出出現如下清況
a=0000 0000 0000 0000 0000 0000 0111 1011
0000 0000 0000 0000 0000 0000 0100 0000
此時輸出的結果就是 100 0000轉爲十進制 爲64
因此不建議對1 進行移位操作,就算是對1 進行移位操作也不能用十進制的方式輸出。
// if(a&(1 << i))
{
printf("1 ");
}
else
{
printf("0 ");
}
交換兩個變量(不創建臨時變量)
#include<stdio.h>
#include<windows.h>
#pragma warning(disable:4996)
int main()
{
//不允許創建臨時變量,交換兩個整數的內容
int a = 0;
int b = 0;
printf("請輸入兩個要交換的變量:>\n");
scanf("%d %d", &a, &b);
a = a^b;
b = a^b;
a ^=b;
printf("a=%d,b=%d\n", a, b);
system("pause");
return 0;
}
a = a^b 異或操作之後 此時把 a 想象成一個密碼,與b按位異或後可以解出 a 同理 與a按位異或後可以解出 b
統計二進制中1的個數
/*
方法一:
思路:
循環進行以下操作,直到n被縮減爲0:
- 用該數據模2,檢測其是否能夠被2整除
- 可以:則該數據對應二進制比特位的最低位一定是0,否則是1,如果是1給計數加1
- 如果n不等於0時,繼續1
*/
int count_one_bit(int n)
{
int count = 0;
while(n)
{
if(n%2==1)
count++;
n = n/2;
}
return count;
}
上述方法缺陷:主要的問題就是對負數沒有辦法進行運算
進行了大量的取模以及除法運算,取模和除法運算的效率本來就比較低。
方法二思路:
一個int類型的數據,對應的二進制一共有32個比特位,可以採用位運算的方式一位一位的檢測,具體如下
int count_one_bit(unsigned int n)
{
int count = 0;
int i = 0;
for(i=0; i<32; i++)
{
if(((n>>i)&1) == 1)
count++;
}
return count;
}
方法二優點:用位操作代替取模和除法運算,效率稍微比較高
缺陷:不論是什麼數據,循環都要執行32次
方法三:
思路:採用相鄰的兩個數據進行按位與運算
可以觀察下:此種方式,數據的二進制比特位中有幾個1,循環就循環幾次,而且中間採用了位運算,處理起來比較高效
int count_one_bit(int n)
{
int count = 0;
while(n)
{
n = n&(n-1);
count++;
}
return count;
}
每次在最右的1設置一個flag的話,
當它(i)它前一位(i-1)進行&操作時,對flag左邊的1是沒有影響的,每次得到的結果,就會將flag位置及右邊所有的數置爲0.指路一個詳解
求兩個數二進制中不同位的個數
思路:
- 先將m和n進行按位異或,此時m和n相同的二進制比特位清零,不同的二進制比特位爲1
- 統計異或完成後結果的二進制比特位中有多少個1即可
#include <stdio.h>
int calc_diff_bit(int m, int n)
{
int tmp = m^n;
int count = 0;
while(tmp)
{
tmp = tmp&(tmp-1);
count++;
}
return count;
}
int main()
{
int m,n;
while(scanf("%d %d", &m, &n) == 2)
{
printf("%d\n", calc_diff_bit(m, n));
}
return 0;
}