设置和获取某位需要一个掩码mask, 掩码的就是只有要操作的位为1, 其他位都为0的值.
比如要操作值value的位7, 则掩码是 0100 0000, 要操作位6, 掩码是 0010 0000...
生成位n的掩码的表达式为:
mask = (1 << n)
设置位7为1的表达式为:
value |= mask
因为, mask只有位7为1, 0 | 1 = 1, 1 | 1 = 1, 所以可以设置位7为1, 而mask的其他位是0, 0 | 0 = 0, 0 | 1 = 1, 也就是不会影响其他位;
设置位7为0的表达式为,:
value &= ~mask
因为, ~mask只有位7为0, 其他位都为1, 而 0 & 0 = 0, 1 & 0 = 0, 可以设置位7为1, 对于其他位, 0 & 1 = 0, 1 & 1 = 1, 没有影响.
根据布尔值b(b=0或b=1)来设置位7的表达式为:
value = (value & mask) | (b << 7)
以上表达式可以推广到多个位, 只需要修改掩码就可以轻松做到.
比如同时设置位7和位1为1, 掩码为 0100 0010, 也就是将位7的掩码和位1的掩码执行 位或得到, 表达式为:
value |= (mask1 | mask7)
同时设置位7和位1为0, 掩码同样是 0100 0010, 表达式为:
value &= ~(mask1 | mask7)
判断多个条件是否满足(多位同时为1)的表达式为:
(value & (mask1 | mask2 | ... | mask)) != 0
其中, mask1, mask2, maskn 是n个条件对应位的掩码. 比如要用位7表示是否长头发, 用位1表示是否结婚, 那么同时长头发与结婚可以用 (value & 0100 0010) != 0 判断
运用:
//这里就是要把数字x的第n位(bit(n-1)位)置为1
//1U就表示的是无符号的1,宏定义可以传参的
#define SET_BIT(x, n) (x | 1U<<(n-1))
//这里就是要把数字x的第n位(bit(n-1)位)清零
#define CLEAR_BIT(x, n) (x & ~(1U<<(n-1)))
//这里就是要把数字x的第n到m位置为1(n是低位,m是高位)
//就是先把0取反就可以得到很多的1,然后左移就得到那么多个0,再取反就可以得到你想要的1的个数了
//最后左移位或就可以置1了
#define SET_BITS(x, n, m) (x | ~(~0U<<(m-n+1))<<(n-1))
//截取变量的部分连续位。(就是取出的意思)
//其实和上面那里是差不多的,后面那一大部分都是为了确定需要多少个1
//最后记得右移,为了得出那个数字
#define GET_BIT(x, n, m) (x & ~(~0U<<(m-n+1))<<(n-1)) >>(n-1)