宏定义在位运算中的运用
目录
1.用宏定义将32位数x的第n位(bit0算第一位)置位 #define SET_BIT(x,n) (x|(1U<<(n-1)))
2.用宏定义将32位数x的第n位(bit0算第一位)清零 #define CLEAR_BIT(x,n) (x&~(1U<<(n-1)))
3.用宏定义将32位数x的第n到m位置位 #define SET_BIT_N_M(x,n,m) (x|((~((~0U)<<(m-n+1)))<<(n-1)))
4.用宏定义将32位数x的第n到m位清零 #define CLEAR_BIT_N_M(x,n,m) (x&~((~((~0U)<<(m-n+1)))<<(n-1)))
5.获取变量X的特定位 #define GETBITS(x,n,m) (x&((~((~0U)<<(m-n+1)))<<(n-1)))>>(n-1)
实现说明:
1和2较为简单就不解释了,直接看代码就行;
以“3.用宏定义将32位数x的第n到m位置位”为例:
例:a = SET_BIT_N_M(a,2,5); //n=2,m=5
第一步:0U,代表32位的unsigned int型的变量,值为0,如下图;
bit号 | 31 | ... | 5 | 4 | 3 | 2 | 1 | 0 |
位号 | 32 | ... | 6 | 5 | 4 | 3 | 2 | 1 |
值 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
第二步:~0U,将0U按位取反,即bit0(第1位)到bit31(第32位)都为1,如下图;
bit号 | 31 | ... | 5 | 4 | 3 | 2 | 1 | 0 |
位号 | 32 | ... | 6 | 5 | 4 | 3 | 2 | 1 |
值 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
第三步:( (~0u) <<(m-n+1) ), 将上一步结果左移(m-n+1)位,如下图;
bit号 | 31 | ... | 5 | 4 | 3 | 2 | 1 | 0 |
位号 | 32 | ... | 6 | 5 | 4 | 3 | 2 | 1 |
值 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
第四步:(~((~0u)<<(m-n+1))),将上一步结果按位取反,如下图;
bit号 | 31 | ... | 5 | 4 | 3 | 2 | 1 | 0 |
位号 | 32 | ... | 6 | 5 | 4 | 3 | 2 | 1 |
值 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
第五步:(~((~0u)<<(m-n+1)))<<(n-1),将上一步结果向左移动(n-1)位,如下图;
bit号 | 31 | ... | 5 | 4 | 3 | 2 | 1 | 0 |
位号 | 32 | ... | 6 | 5 | 4 | 3 | 2 | 1 |
值 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |
第六步:采用位或,将特定位置为1
4就是在3的第五步后面再取个反,然后和x与;
5就是在3的基础上,将或改成与,并且将得到的数据移回最低位,所以最后加上右移(n-1)位。
实现代码:
1 #include<iostream> 2 using namespace std; 3 4 #define SET_BIT(x,n) (x|(1U<<(n-1))) 5 #define CLEAR_BIT(x,n) (x&~(1U<<(n-1))) 6 #define SET_BIT_N_M(x,n,m) (x|((~((~0U)<<(m-n+1)))<<(n-1))) 7 #define CLEAR_BIT_N_M(x,n,m) (x&~((~((~0U)<<(m-n+1)))<<(n-1))) 8 #define GETBITS(x,n,m) (x&((~((~0U)<<(m-n+1)))<<(n-1)))>>(n-1) 9 10 int main() 11 { 12 //定义变量 13 unsigned int a = 0; 14 char a_str[35] = {0}; 15 16 //1.用宏定义将32位数x的第n位(bit0算第一位)置位 17 cout<<"1.用宏定义将32位数x的第n位(bit0算第一位)置位"<<endl; 18 itoa(a, a_str, 2); 19 cout << "原始数(二进制):" << a_str << endl; 20 a = SET_BIT(a,4); 21 itoa(a,a_str,2); 22 cout<<"置位后(二进制):"<<a_str<<endl; 23 cout<<endl; 24 25 //2.用宏定义将32位数x的第n位(bit0算第一位)清零 26 cout << "2.用宏定义将32位数x的第n位(bit0算第一位)清零" << endl; 27 itoa(a, a_str, 2); 28 cout << "原始数(二进制):" << a_str << endl; 29 a = CLEAR_BIT(a, 4); 30 itoa(a, a_str, 2); 31 cout << "清零后(二进制):" << a_str << endl; 32 cout << endl; 33 34 //3.用宏定义将32位数x的第n到m位置位 35 cout << "3.用宏定义将32位数x的第n到m位置位" << endl; 36 itoa(a, a_str, 2); 37 cout << "原始数(二进制):" << a_str << endl; 38 a = SET_BIT_N_M(a,2,5); 39 itoa(a, a_str, 2); 40 cout << "置位后(二进制):" << a_str << endl; 41 cout << endl; 42 43 //4.用宏定义将32位数x的第n到m位清零 44 cout << "4.用宏定义将32位数x的第n到m位清零" << endl; 45 itoa(a, a_str, 2); 46 cout << "原始数(二进制):" << a_str << endl; 47 a = CLEAR_BIT_N_M(a, 2, 5); 48 itoa(a, a_str, 2); 49 cout << "清零后(二进制):" << a_str << endl; 50 cout << endl; 51 52 //5.获取变量X的特定位 53 a = 0x00f0; 54 cout << "5.获取变量X的特定位" << endl; 55 itoa(a, a_str, 2); 56 cout << "原始数(二进制):" << a_str << endl; 57 a = GETBITS(a, 5, 8); 58 itoa(a, a_str, 2); 59 cout << "获取后(二进制):" << a_str << endl; 60 cout << endl; 61 62 system("pause"); 63 return 0; 64 }
——如有不对的地方,非常欢迎给予指导!
如有不对的地方,非常欢迎给予指导!
如果您觉得这篇文章对您有所帮助,您可以点击右边的“打赏”功能,也可以点击下方的“好文要顶”按钮,因为这两种肯定,都让我更加相信自己所做的工作是有意义的,也是支持我继续写下去的最大动力!
感谢您给予的支持!