输入一个数对应二进制下遇到的问题归纳

来源:互联网 发布:深圳市市政院 知乎 编辑:程序博客网 时间:2024/05/29 17:47

在学习C的过程中,有时候会出现关于一个数二进制情况下的问题。

例如:1>输入一个数,输出这个数二进制中1或者0的个数;2>输入一个数,输出二进制下对应的偶数位和奇数位组成的序列;....此类问题


解释这个问题之前,首先需要简单介绍位操作符和移位操作符:

位操作符:

1>:&为AND操作符,对应位同为1结果则为1,否则为0;

2>:|为OR操作符,对应位如果为0时结果为0;否则为1;

3>:^为XOR操作符,如果两个位不同时结果为1;相同则为0。

例如: a = 00101110; b = 01011011; a & b 结果为00001010; a | b 结果为01111111; a ^ b 结果为01110101 。

移位操作符:其实移位操作符只是简单的把一个值得位向左或向右移动给定的位数,其中左移时最左边被移出去的值被丢弃,最右侧多出的空位则由0来补齐







右移同理,但是在左侧填充位时,会分为逻辑移位和算术移位:

1>逻辑移位:左边移入的位用0填充;

2>算术移位:当符号位为1时,则移入的位都为1;

                      当符号位为0时,则移入的位都为0。

注:给定需移位的数字都必须为整数类型!


接下来就来分析下第一个题目:

1>给定一个数,输出对应二进制中1的个数:

第一种:

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<windows.h>int main(){int num = 15;                //只能为正数int count = 0;               //统计出现1的次数while (num){if (num % 2 == 1){count++;}num = num / 2;}printf("count = %d\n", count);system("pause");return 0;}
这种方法利用短除法是比较容易想到的,但是有一个缺陷!num值一旦等于负数的时候,该代码将不再适用。

第二种:

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<windows.h>int main(){int num = -1;              //可任意取整型值int i = 0;int count = 0;for (i = 0; i < 32; i++)   //内存中一个int占4个字节=32个位{if (((num >> i) & 1) == 1) //请看下面解释{count++;}}printf("%d", count);system("pause");return 0;}

解释下 ((num >> i) & 1) == 1是如何判定的:

  假设用户输入15,内容中存放的是补码,正数的原码补码相同。同时,一个整型类型占用四个字节也就是32个位,所以15在内存中表示为:0000 0000 0000 1111;代码中num>>i代表num按照i的值右移i位,接下来再进行&1运算,此时进行移位操作后,如果最后一位为1再进行&1运算后,结果为1,对应的count加1;反之结果为0。


2>分别输出一个十进制数对应二进制中偶数位和奇数位的数字:

代码如下:

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<windows.h>int main(){int num = 10;int i = 0;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);}system("pause");return 0;}

通过上一个问题的解释,这个问题也就变得简单了。读者只需要按顺序一步一步阅读下去即可了解。


欢迎大家关注此公众号和我们一起进行交流和学习,我们会定期谈谈自己对一些知识点的理解以及一些需要注意的地方。


                                                                                                    



2 0