按照二进制位一一对应,只有全1才为真,否则为假
特定位置置0用位与 &
按照二进制,有真则真,全假才假
特定位置置1用位或 |
按照二进制位,1变为0,0变为1
逻辑取反 !
数当成整体,不变二进制。不是0就是1,是0才为0
任何非0的数被按逻辑取反再取反就会得到1;
任何非0的数倍按位取反再取反就会得到他自己;
int main(void)
{
unsigned int a = 45;
unsigned int b, c;
b = ~a; // 按位取反
c = !a; // 逻辑取反
printf("b = %un", b); // b = 4294967250
printf("c = %un", c); // c = 0
return 0;
}
4.位异或 ^
按二进制来对比,两个数相同为0,不同为1
5.移位 << >>对于无符号数,左移时右侧补0(相当于逻辑移位)
对于无符号数,右移时左侧补0(相当于逻辑移位)
对于有符号数,左移时右侧补0(叫算术移位,相当于逻辑移位)
对于有符号数,右移时左侧补符号位(如果正数就补0,负数就补1,叫算术移位)
负数第一位位符号数,为1
int main(void)
{
// 设置就是赋值为1,清除就是赋值为0
unsigned int a = 1;
unsigned int b = 0;
a = a | 0x01<<3;// 给定一个整型数a,设置a的bit3,保证其他位不变。
a = a | 0x1f<<3;// 给定一个整形数a,设置a的bit3~bit7,保持其他位不变。
a = a & 0xffff3fff;// 给定一个整型数a,清除a的bit15,保证其他位不变。
a = a & (~(0x00001ff<<15));// 给定一个整形数a,清除a的bit15~bit23,保持其他位不变。
// 给定一个整形数a,取出a的bit3~bit8。
a = a & 0x3f<<3; a >>= 3;// 先将其他位置为0,然后右移三位
// 给一个寄存器的bit7~bit17赋值937(其余位不受影响)。
a = a & ~(0x3ff<<7);// 先将7-17的值清零
a |= 937<<7;// 7-17赋值937
// 将一个寄存器的bit7~bit17中的值加17(其余位不受影响)。
b = a & (0x3ff<<7); b >>= 7;// 将7-17的值取出,不能将其他位置为0
b = b += 17;// 将值加上17
a = a & ~(0x7ff>>7);// 将7-17清零,然后写入b的值
a |= b<<7;// 将b赋值到7-17位
// 给一个寄存器的bit7~bit17赋值937,同时给bit21~bit25赋值17。
// 可以像前面一样分两次进行,效率低,所以要二合一解决
a = a & ~((0x3ff<<7) | (0x1f<<21));
a |= ((937<<7) | (17<<21));
printf("a = %un", a);
return 0;
}
// 用宏定义来完成位运算
// 用宏定义将32位数x的第n位置位,置1(右边起算,bit0算第一位)
#define SET_BIN_N(x, n) (x | (1U<<(n-1))) // 加上U表示1是无符号的数
// 用宏定义将32位数x的第n位清零
#define CLEAR_BIN_N(x, n) (x & ~(1U<<(n-1)))
// 用宏定义将32位数的第n位到第m位置位
#define SET_BIN_N_M(x, n, m) (x | (~(~(0U)<<(m-n+1))<<(n-1)))
// 第一步:先得到全是1的数 ~(0U)
// 第二步:先将其左移 ,移出m-n+1个0 ~(0U)<<(m-n+1)
// 第三步:然后将其取反,得到m-n+1个1 ~(~(0U)<<(m-n+1))
// 第四步:然后将其左移n-1位 ~(~(0U)<<(m-n+1))<<(n-1)
// 第五步:让x与之按位或,得到n-m位为1 (x | (~(~(0U)<<(m-n+1))<<(n-1)))
int main(void)
{
unsigned int a = 0;
unsigned int b = 0;
b = SET_BIN_N_M(a, 4, 8);
printf("b = 0x%xn", b);// b = 0xf8
}
// 将中间n-m位取出
#define GETBITS(x, n, m) ((x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1))
// 第一步:先得到全1数,然后左移m-n+1位,m-n+1位0,其他位为1 ~(0U)<<(m-n+1)
// 第二步:然后再将其取反,得到m-n+1位为1,其他位为0 ~(~(0U)<<(m-n+1))
// 第三步:将其左移到n-m位上 ~(~(0U)<<(m-n+1))<<(n-1)
// 第四步:然后将x与之位与,改变其他位,不改变n-m位 (x & ~(~(0U)<<(m-n+1))<<(n-1))
// 第五部:将该数右移n-1位,得到n-m位的数



