码迷,mamicode.com
首页 > 其他好文 > 详细

位运算

时间:2017-03-26 14:23:26      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:题目   its   定义   printf   寄存器   变量   区别   应该   相同   

位运算
1.位与 & 逻辑与 &&
区别:0xAA&0xF0=0xA0 0xAA&&0xF0=1 位与一位一位进行相与,有0则0;逻辑与则是把这一个数当成一个整数,两个非0则为1
一个为0则输出0

2.位或 | 逻辑或 ||
区别:0xAA|xF0=0xFA 0xAA||0xF0=1 位或一位一位进行相或,有1就1;逻辑或还是把那个数字当成一个整数,有一个非0则是1
两个都为0才输出0

3.位取反 ~ 逻辑取反!
区别:一位一位取反,0取反就是1,1取反就是0;逻辑取反则是,非0的取反均为0,0取反为1

4.位异或 ^
相异出1,相同则出0


例子:
用C语言将一个寄存器的bit7~bit17中的值加17(其余位不受影响)。
思路:第一步,先读出原来bit7~bit17的值
第二步,给这个值加17
第三步,将bit7~bit17清零
第四步,将第二步算出来的值写入bit7~bit17

 

unsigned int a = 0xc30288f8;    // 0xc34648f8
unsigned int tmp = 0;
tmp = a & (0x3ff<<7); //第一步 
tmp >>= 7;    
tmp += 17;    //第二步,先将得到的值右移再加上17
a &= ~(0x3ff<<7); //第三步 
a |= tmp<<7;    //第四步
printf("a = 0x%x.\n", a);

 


用宏定义来完成位运算
1.直接用宏来置位、复位(最右边为第1位)。

#define SET_NTH_BIT(x, n) (x | ((1U)<<(n-1)))
#define CLEAR_NTH_BIT(x, n) (x & ~((1U)<<(n-1)))

例子:用宏定义将32位数x的第3位(右边起算,也就是bit0算第1位)置位,第13位清0

#define SET_BIT_N(x, n) (x | (1U)<<(n-1))
#define    CLEA_BIT_N(x, n) (x ~ (1U << (n-1)))

int main(void)
{
unsigned int a = 0xFFFFFFFF;    
unsigned int b = 0,c = 0;
b = CLEAR_BIT_N(a,13);
c = SET_BIT_N(a, 3);
printf("b = 0x%x.\n", b);
printf("c = 0x%x.\n", c);

}

 


2、截取变量的部分连续位。例如:变量0x88, 也就是10001000b,若截取第2~4位,则值为:100b = 4
#define GETBITS(x, n, m) ((x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1)) //0U取反后则32位全为1

这个题目相当于是要把x的bit(n-1)到bit(m-1)取出来
复杂宏怎么分析:

((x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1))
第一步,先分清楚这个复杂宏分为几部分:2部分
(x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1)
分析为什么要>>(n-1),相当于是我们4.2.4.5中的第二步

第二步,继续解析剩下的:又分为2部分
x & ~(~(0U)<<(m-n+1))<<(n-1)
分析为什么要&,相当于我们4.2.4.5中的第一步

第三步,继续分析剩下的:
~ (~(0U)<<(m-n+1)) << (n-1)
这个分析时要搞清楚第2坨到底应该先左边取反再右边<<还是先右边<<再左边取反。
解法:第一,查C语言优先级表;第二,自己实际写个代码测试。
说明这个式子应该是 ~(~(0U)<<(m-n+1)) << (n-1) ,这就又分为2部分了


(参考朱友鹏老师 )

 

位运算

标签:题目   its   定义   printf   寄存器   变量   区别   应该   相同   

原文地址:http://www.cnblogs.com/ziv3/p/6621515.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!