对于计算机内存中以二进制存储的数据来说,想要在其基础上进行简单的操作,显然,对于初学者来说,并不算是简单,但是,只要搞清楚原理方法后,也是很简单滴。。。下面,我将以两道题为例,简单介绍:
题目:获取一个数二进制序列中所有的偶数位和奇数位,分别输出二进制序列
这里,我运用最笨或者说最直接的做法,用两个数组分别存储奇数位和偶数位,然后循环,若当前为第奇数次循环,将该最低位存入奇数数组,同理,得到偶数数组
//分离奇偶序列函数 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; }运行结果: 计算器验证:
这是较为聪明的方法^_^: 不改变原数组的值,既然已知为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);用 移位运算 + 三目运算符的嵌套形式 来进行