【原创】C/C++宏定义在位运算中的运用

目录

  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...543210
位号32...654321
00000000

      第二步:~0U,将0U按位取反,即bit0(第1位)到bit31(第32位)都为1,如下图;

bit号31...543210
位号32...654321
11111111

      第三步:( (~0u) <<(m-n+1) ), 将上一步结果左移(m-n+1)位,如下图;

bit号31...543210
位号32...654321
11110000

      第四步:(~((~0u)<<(m-n+1))),将上一步结果按位取反,如下图;

bit号31...543210
位号32...654321
00001111

      第五步:(~((~0u)<<(m-n+1)))<<(n-1),将上一步结果向左移动(n-1)位,如下图;

bit号31...543210
位号32...654321
00011110

      第六步:采用位或,将特定位置为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 }

——如有不对的地方,非常欢迎给予指导!

  如有不对的地方,非常欢迎给予指导!

  如果您觉得这篇文章对您有所帮助,您可以点击右边的“打赏”功能,也可以点击下方的“好文要顶”按钮,因为这两种肯定,都让我更加相信自己所做的工作是有意义的,也是支持我继续写下去的最大动力!

  感谢您给予的支持!