下面以两道进制转换习题为例实现位运算进制转换:
- 输入一个十进制整数(正、负),转换为二进制显示,不能用算术运算符,只能用位操作符。
void toBinary(int n) { int a[8]={0}; for(int i = 0;i<8;i++) a[7-i] = (n>>i)&1; for(int i = 0;i<8;i++) printf("%d",a[i]); }
实现原理:
数n在内存中以二进制存储,;例如:17以000010001存储,通过位运算可以直接将其取出 而不用进行算数运算,(n>>i)以n=17为例,当i=0时,00010001右移0为即还是00010001 和1进行与运算,补充与运算知识
1 & 1 = 1;
1 & 0 = 0;
0 & 1 = 0;
0 & 0 = 0;
00010001和00000001进行与运算后得到00000001即1,同理当i=1时(17>>1)得到 00001000,与00000001进行与运算后得到00000000即0,同理i=2、3 时都为0,i=4时为1, 其余均为0,即可得到00010001。
以上举例为正数右移,不同系统对带符号负数的右移方式可能不同,有的系统是逻辑右移, 即高位补0;有的系统是算术右移,即高位补1。可自行编写程序验证本系统中右移操作是逻 辑右移还是算术右移。程序对正负数均有效。
以下代码更加简洁:
void toBinary(int n)
{
for(int i = 0;i<8;i++)
printf("%d",(n>>7-i)&1);
}
2.输入一个十进制整数(正、负),转换为十六进制显示,即实现printf(“%x”,x)的功能,但不能用这个函数,也不能用算术运算符,只能用位操作符。
void toHex(int num)
{
if (num == 0)
{
printf("0");
return ;
}
char str[100] = {0};
int index = 0;
for (int i = 0; i < 8; i ++)
{
int temp = (num >> (4 * (7-i))) & 0xF;
if (index > 0 || val > 0)
{
char ch = temp < 10 ? (char) ('0' + temp) : (char) ('A' + temp - 10);
str[index++] = ch;
}
}
for(int i=0;i<index;i++)
printf("%c",str[i]);
}
和二进制不同的是这里num右移4*(7-i)并和15进行与运算
int temp = (num >> (4 * (7-i))) & 0xF;