对于计算机内存中以二进制存储的数据来说,想要在其基础上进行简单的操作,显然,对于初学者来说,并不算是简单,但是,只要搞清楚原理方法后,也是很简单滴。。。下面,我将以两道题为例,简单介绍:
一:
题目:获取一个数二进制序列中所有的偶数位和奇数位,分别输出二进制序列
方法1:
这里,我运用最笨或者说最直接的做法,用两个数组分别存储奇数位和偶数位,然后循环,若当前为第奇数次循环,将该最低位存入奇数数组,同理,得到偶数数组
//分离奇偶序列函数
void getSequence(int o[], int e[], int value)
{
int c = 0; //控制循环变量
int m = 0, n = 0; //分别控制等待存的数组的下标
while (c < 32){
if (c % 2 == 0){ //也可以为 c&1 ,判断c的奇偶
o[m] = value & 1;
m++;
}
else{
e[n] = value & 1;
n++;
}
value >>= 1;
c++;
}
}
为便于观察,将输入数分解为二进制并展示出来:
//将数分解为二进制序列函数
void FullSequence(int f[],int value)
{
int c = 0;
while (c < 32){
if (value & 1){
f[c] = value & 1;
}
else{
f[c] = value & 1;
}
value >>= 1;
c++;
}
}
打印函数模块:
void PrintArr(int a[],int Max)
{
int i = Max-1;
for (; i >=0; i--){
printf("%d ", a[i]);
}
printf("\n");
}
主函数模块:
int main()
{
int odd[16] = { 0 };
int even[16] = { 0 };
int full[32] = { 0 };
int number = 0;
printf("请输入一个数用以分离它的二进制奇偶序列:");
scanf("%d", &number);
//将输入的数以二进制形式输出
FullSequence(full, number);
PrintArr(full, 32);
//分离奇偶序列
getSequence(odd,even,number);
//输出
printf("偶数位序列为 :");
PrintArr(odd,16);
printf("奇数位序列为 :");
PrintArr(even,16);
system("pause");
return 0;
}
运行结果:
计算器验证:
方法2:
这是较为聪明的方法^_^:
不改变原数组的值,既然已知为32位地址,那么不妨按照输出的顺序从左只有与0按位相与,所以移动该数的二进制序列,从最大的奇/偶数位至最小的奇/偶数位,但不改变二进制序列的值
void getSequence(int num)//全部从左边开始,不改变输入的数的原值,只是在其基础上向右移动一定的位数
{
int i = 0;
//偶数
printf("偶数位序列为:");
for (i = 31; i >= 1; i -= 2){
printf("%d ", (num >> i) & 1);
}
printf("\n");
//奇数
printf("奇数位序列为:");
for (i = 30; i >= 0; i -= 2){
printf("%d ", (num >> i) & 1);
}
printf("\n");
}
主函数模块:
需要调用方法1中的输出该数二进制序列的函数和打印序列函数
int main()
{
int full[32] = { 0 };//方便打印原数组以供观察
int number = 0;
printf("请输入一个数用以分离它的二进制奇偶序列:");
scanf("%d", &number);
//将输入的数以二进制形式输出
FullSequence(full, number);
PrintArr(full, 32);
//分离奇偶序列
getSequence(number);
system("pause");
return 0;
}
得出结果与方法1一致!
二:
题目:求两个int(32位)整数m和n的二进制表达中,位(bit)不同的个数
题目与上一题基本一致,不过就是将其间的分离奇偶数位换成按位比较个数,处理办法基本相同,
将两个数分别取最低位进行比较,若不同,则计数器加一,然后向右移动1为进入下一循环…
int Compare_By_Bit(int m, int n)
{
int count = 0;
//若m,n有一个不为零,不然存在不相同的位,故仍需进行比较,直到两者都为零为止
while (m || n){
if ((m & 1) != (n & 1)){ //两者分别求最低位的值,进行比较
count++;
}
m >>= 1; //移位,右移一位,比较下一位
n >>= 1;
}
return count;
}
为便于观察结果,设置将函数将数转化为二进制序列并显示,与上题相同
//将数分解为二进制序列
void FullSequence(int f[], int value)
{
int c = 0;
while (c < 32){
if (value & 1){
f[c] = value & 1;
}
else{
f[c] = value & 1;
}
value >>= 1;
c++;
}
}
输出模块:
//输出
void PrintArr(int a[], int Max)
{
int i = Max - 1;
for (; i >= 0; i--){
printf("%d ", a[i]);
}
printf("\n");
}
主函数:
#include<stdio.h>
#include<Windows.h>
#pragma warning (disable:4996)
int main()
{
int m, n;
int res = 0;
int fulla[32] = { 0 };
int fullb[32] = { 0 };
printf("输入两个数以进行位比较:");
scanf("%d %d", &m, &n);
FullSequence(fulla, m);
PrintArr(fulla,32);
FullSequence(fullb, n);
PrintArr(fullb, 32);
res=Compare_By_Bit(m, n);
printf("不相同的位数有 %d 个 \n", res);
system("pause");
return 0;
}
运行结果:
结果验证:
三、
这里简单提一下关于两个数比较大小的位运算
要求:不使用大于、小于、if 等操作来进行判断
(a-b)>>31 ? -1 : ((a-b) ? 1 : 0);
用 移位运算 + 三目运算符的嵌套形式 来进行