1,在实际的位运算当中,我们通常需要知道二进制、八进制、十进制、十六进制之间的转换,
这里我们以十六进制作为例子
例如;x=0x27,y=0x3f ;
0x27=0010 0111
0x3f=0011 1111
当我们需要将x进行移位操作时;看自己需要移多少位,假如我们移三位;
#include
int main(int argc, const char *argv[])
{
unsigned char x=0x27,y=0x3f,z,f,a=5;//为无符号字符型
z=x<<3;//将x左移三位
f=x>>3;//将y右移三位
printf("%#x,%#x\n",z,f);
return 0;
}
看输出结果
0x38,0x4
x左移3位之后赋给z=0x38=0011 1000 ;y右移3位赋给f=0x04;这里显示0x4,在Linux系统下会自动省略0,则现在f=0x4=0000 0100 ;可以很清楚的看到进行移位之后的数据,这里过程当中有一个比较容易不清楚的地方,就是在移位过程中;
原来是0x27=0010 0111
移位过程中 001 0011 1000 000
移位之后 0011 1000
这里要注意移位过程中前面的数移出去以后,后面补0,而不是循环到第一位,这种理解方式是错误的
这里我们就要利用前面说过的移位操作;
那要如何进行置1,清0呢?在C语言当中我们利用 |(或)来置1 ,用 &(与)来清0
当我们想要某一位快速置1,可以将原数据或上0000 0001,也就是1,例如需要将y第6位置1;
将x第2位清0;代码如下;
#include
int main(int argc, const char *argv[])
{
unsigned char x=0x27,y=0x3f,z,f,a=5;
z=x&~(1<<(a-3));//将x第2位清0
f=y|(1<<(a+1));//将x第6位置1
printf("z=%#x,f=%#x\n",z,f);
return 0;
}
这里需要注意的是,我们进行清0用的是&(与)运算,两个真才为1,一个真一个假为0,而这里我们清0的是第二位
0x27=0010 0111
1=0000 0001
1<<2表示1左移两位 0000 0100
~1<<2表示将移位之后取反 1111 1011
将得到的取反和0x27相与得到
0x27=0010 0111
取反后1111 1011
0010 0111
& 1111 1011
0010 0011
=0x23
置1过程也是这样,这里留给读者自己下去尝试一遍
代码运行结果如下
z=0x23,f=0x7f
接下来就是如何利用位运算把十进制转化位十六进制;
我们都知道
先看代码;
#include
int main(int argc, const char *argv[])
{
int a=65,b=0;
printf("%#x,%d,%#x,%d\n",a,a,b,b);
b=a>>4;//将a取整
printf("%#x,%d,%#x,%d\n",a,a,b,b);
b=a&0xf;//将a取余
printf("%#x,%d,%#x,%d\n",a,a,b,b);
return 0;
}
运行结果
0x41,65,0,0
0x41,65,0x4,4
0x41,65,0x1,1
代码当中的取整和取余是怎么来呢;
a=65 转化为十六进制为0x41=0100 0001
65= 4*16+4*1
当我们将a右移4位后得到的就是取整后的数
0x04=0000 0100
大家肯定疑惑为什么右移4位就是取整后的数了呢
我们知道在数学当中65/16=4.....1
当我们计算某一个数运算除法的时候例如 %(取余) /(取整)
在C语言中65/16=4 65%16=1
在65(十进制)转化为 0x41(十六进制) 在0x41当中 4就是取整的,1就是取余的
我们移位就是将余数1给剔除掉,计算其他数也是一样的,例如a=2665
代码如下
#include
int main(int argc, const char *argv[])
{
int a=2665,b=0;
printf("%#x,%d,%#x,%d\n",a,a,b,b);
b=a>>4;
printf("%#x,%d,%#x,%d\n",a,a,b,b);
b=a&0xf;
printf("%#x,%d,%#x,%d\n",a,a,b,b);
return 0;
}
运行结果
0xa69,2665,0,0
0xa69,2665,0xa6,166
0xa69,2665,0x9,9
可以看到2665转化为十六进制为0xa69,右移4位,取整得到166,取余为9
取余过程和上面道理一样,上面是将余数给剔除掉,取余的过程就是把取整给剔除掉,
由于余数是0-15,所以在我们取余的时候只保留余数部分
例如;
0x41=0100 0001
&0000 1111
= 0000 0001
所以得到余数1,这里要理解我们的目的是得到余数,不需要整数,取余的过程相当于将不是余数的部分清0,清0用&;
整数部分不要&0,余数部分保留&1
以上就得到基本的位操作