1.统计一个数的二进制数中1的个数
内容:
写一个函数返回参数二进制中 1 的个数。
比如: 150000 1111 4个1
方法1:
//统计二进制中1的个数
#include<stdio.h>
int count_num_of_1(int n)
{
int count = 0;
while (n)//n如果不是0,说明它的二进制位一定有1
{
if ((n % 2) == 1)
{
count++;
}
n /= 2;
}
return count;
}
int main()
{
int num = 0;
scanf("%d", &num);
int n = count_num_of_1(num);
printf("%d\n", n);
return 0;
}
以上代码一个小问题,当num是正数的时候,它能计算的结果是正确的;但是当num是负数时,它计算的结果是错误的。
那为什么会出现以上结果呢?
改进方式:
//统计二进制中1的个数 #include<stdio.h> //int count_num_of_1(int n) int count_num_of_1(unsigned int n) { int count = 0; while (n) { if ((n % 2) == 1) { count++; } n /= 2; } return count; } //-1 //10000000 00000000 00000000 00000001 原码 //11111111 11111111 11111111 11111110 反码 //11111111 11111111 11111111 11111111 补码 // 如果将(11111111 11111111 11111111 11111111)放到无符号数里面, // 那么编译器就会认为第一个1不再是符号位,而是一个很大的正数 //num=-1时,计算的结果应该是32 int main() { int num = 0; scanf("%d", &num); int n = count_num_of_1(num); printf("%d\n", n); return 0; }
方法2:
要想得到一个数的二进制位中1的个数,可以将二进制位数一个一个拿出来,再判断它是否为1.
#include<stdio.h> int count_num_of_1(int n) { int i = 0; int count = 0; for (i = 0; i < 32; i++) { if ((n >> i) & 1 == 1) { count++; } } return count; } int main() { int num = 0; scanf("%d", &num); int n = count_num_of_1(num); printf("%d\n", n); return 0; }
方法3:
以上两种方法效率都不够高。
#include<stdio.h> int count_num_of_1(int n) { int count = 0; while (n) { n = n & (n - 1); count++; } return count; } int main() { int num = 0; scanf("%d", &num); int n = count_num_of_1(num); printf("%d\n", n); return 0; }
2.判断一个数是不是2的次方
#include<stdio.h> int Is_num(int n) { if ((n & (n - 1)) == 0)//因为(n & (n - 1)这个表达式每执行一次,就会去掉一个1 return 1; else return 0; } int main() { int num = 0; scanf("%d", &num); int flag = Is_num(num);//如果是则返回1,不是则返回0 if (flag == 1) printf("%d是2的次方\n", num); else printf("%d不是2的次方\n", num); return 0; }
3.求两个数二进制中不同位的个数
作业内容
编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
输入例子:
1999 2299
输出例子:7
方法1:
#include<stdio.h> int count_diff_bit(int m, int n) { int i = 0; int count = 0; for (i = 0; i < 32; i++) { if (((m >> i) & 1) != ((n >> i) & 1)) { count++; } } return count; } int main() { int m = 0; int n = 0; scanf("%d %d", &m, &n); int ret = count_diff_bit(m, n); printf("ret=%d\n", ret); return 0; }
方法2:
^ 异或操作符——相同为0,相异为1。所以只需要统计m^n中二进制数中有几个1,就是m和nn的二进制表达式中,有多少个位(bit)不同?
#include<stdio.h> int count_diff_bit(int m, int n) { int count = 0; int ret = m ^ n; while (ret) { ret = ret & (ret - 1); count++; } return count; } int main() { int m = 0; int n = 0; scanf("%d %d", &m, &n); int ret = count_diff_bit(m, n); printf("ret=%d\n", ret); return 0; }
4.打印整数二进制的奇数位和偶数位
作业内容
获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列。
//获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列 //00000000 00000000 00000000 00001010 - 认为最左边的为第一位 #include<stdio.h> int main() { int i = 0; int num = 0; scanf("%d", &num); //获取奇数位数字 for (i = 30; i >= 0; i -= 2) { printf("%d ", (num >> i) & 1); } printf("\n"); //获取奇数位数字 for (i = 31; i >= 1; i -= 2) { printf("%d ", (num >> i) & 1); } return 0; }