1.
写一个函数返回参数二进制中 1 的个数
比如: 15 0000 1111 4 个 1
程序原型:
int count_one_bits(unsigned int value)
{
// 返回 1的位数
}
难点和改良方法已写在注释上
#include<stdio.h>
#include<windows.h>
int count_one_bits(unsigned int value)
{
int count = 0;
int i = 0;
for (i = 0; i<31; i++) //int型的二进制表示范围有32位,要将这三十二位全部右移检测一次
//除了这种方法,还能用while(value)的方式进行循环,因为value每次右移都会左端补一个0,当value等于0时退出循环,故最多循环32次
{
if (value & 1 == 1) //这里利用的是value和二进制的1(0001)进行对比,如果末尾是1,则&结果是1,通过判断count的数量就能判断1的个数
//此处可改进为(value>>i)&1==1(利用的是位移操作符不会改变自身的值,而i++每次加1),则可省略value=value>>1不写
{
count++;
value=value >> 1; //位移操作符和自加自减不同,并不会改变自身的值,所以需要value=value >> 1
}
}
return count;
}
int main()
{
int a = 15;
printf("数字%d的二进制中1的个数为为%d\n", a, count_one_bits(a));
system("pause");
return 0;
}
在&运算中还有一种比较难想到的方法可以统计1的个数,那就是用n = n & (n - 1)
首先是(n - 1)发生了什么:
二进制数n,n-1后,如果最后一位是0,将向前一位借2,2-1=1。最后一位为1。如果前一位为0,将继续向前一位借2,加上本身少掉的1.则变为1。一直遇到1。减为0.
所以 二进制 xxxx10000-1 = xxxx01111
n&n-1产生的结果:
按照上述 n=xxxx10000,n-1=xxxx01111
xxxx10000
xxxx01111
xxxx00000
这里可以看出进行了&运算后,最后一位1被消去了
重复操作,有多少个1,这个操作就可以执行多少次。
2.获取一个数二进制序列中所有的偶数位和奇数位,
分别输出二进制序列。
将所有比特位逐个右移的方法在上面的例子中已经用过,虽然比较直观,但是麻烦,本例用while(n>0)的方法进行循环
#include<stdio.h>
int print(int n)
{
int i = 0;
int m = n >> 1;
//输出偶数位
/*for (i = 31; i > 0; i = i - 2){
printf("%d ", (n >> i) & 1);
}*/
while (n > 0){
printf("%d", n & 1);
n = n >> 2;
}
printf("%\n");
//输出奇数位
/*for (i = 30; i >= 0; i = i - 2){
printf("%d ", (n >> i) & 1);
}*/
while (m > 0){
printf("%d", m & 1);
m = m >> 2;
}
}
int main(){
int i = 9;
print(i);
return 0;
}
3.两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
输入例子:
1999 2299
输出例子:7
#include<stdio.h>
int main(){
int a = 1999;
int b = 2299;
int c = a^b;
//异或运算,二进制中有几个1就有几个位(bit)不同
//然后统计1的个数就能知道有几位(bit)不同
int count = 0;
while (c > 0){
if (c % 2 == 1)
++count;
c = c >> 1;
}
printf("%d\n", count);
return 0;
}
(@_@;)