如何设置、清除和切换单个比特位?
使用标准 C++ 库: std::bitset
。
或者使用 Boost 版本: boost::dynamic_bitset
。
没有必要自己编写:
#include#include int main() { std::bitset<5> x; x[1] = 1; x[2] = 0; // Note x[0-4] valid std::cout << x << std::endl; }
[Alpha:] > ./a.out 00010
Boost 版本允许运行时大小的位集,相比于 标准库 编译时大小的位集。
设置位(bit)
使用按位或(OR)运算符(|
)来设置位(bit)。
number |= 1UL << n;
这将设置number
的第n
位。如果要设置第1
位,n
应该为零,如果要设置第n
位,n
应该为n-1
。
如果number
比unsigned long
更宽,请使用1ULL
;在评估1UL << n
之前,1UL << n
的提升不会发生,在其中移位超过long
的宽度是未定义行为。对所有其他示例都适用相同的规则。
清除位(bit)
使用按位与(AND)运算符(&
)来清除位(bit)。
number &= ~(1UL << n);
这将清除number
的第n
位。您必须使用按位取反(NOT)运算符(~
)反转位字符串,然后进行按位与(AND)运算。
切换位(bit)
按位异或(XOR)运算符(^
)可用于切换位(bit)。
number ^= 1UL << n;
这将切换number
的第n
位。
检查位(bit)
您没有要求这个,但我也可以添加一下。
要检查一个位(bit),将数字n
向右移位,然后进行按位与(AND)运算:
bit = (number >> n) & 1U;
这将把number
的第n
位的值放入变量bit
中。
将第n位更改为x
在2's补码的C++实现中,可以通过以下方式将第n
位设置为1
或0
:
number ^= (-x ^ number) & (1UL << n);
如果x
是1
,则将设置第n
位,如果x
是0
,则将清除第n
位。如果x
具有其他值,则会得到垃圾值。x = !!x
将其布尔化为0或1。
为了让这个操作与2的补码否定行为无关(在1的补码或符号/大小写C++实现中,-1
的所有位都设置,与2的补码不同),应该使用无符号取反。
number ^= (-(unsigned long)x ^ number) & (1UL << n);
或者
unsigned long newbit = !!x; // Also booleanize to force 0 or 1 number ^= (-newbit ^ number) & (1UL << n);
通常最好使用无符号类型进行可移植的位操作。
或者
number = (number & ~(1UL << n)) | (x << n);
(number & ~(1UL << n))
将清除第n
位,而(x << n)
将将第n
位设置为x
。
一般来说最好不要复制/粘贴代码,因此许多人使用预处理器宏(例如下面的社区wiki答案)或某种封装。