使用按位 OR 运算符( |
)设置一个位。
number |= 1UL << n;
这将设置第n
number
。
如果number
宽于unsigned long
,则使用1ULL
; 推广1UL << n
不会发生,直到评估后1UL << n
它是不确定的行为比一的宽度更转向long
。这同样适用于所有其他示例。
使用按位 AND 运算符( &
)清除一位。
number &= ~(1UL << n);
这将清除第n
位number
。必须使用按位 NOT 运算符( ~
)反转位串,然后运行 AND。
XOR 运算符( ^
)可用于切换位。
number ^= 1UL << n;
这将切换n
个位number
。
你没有要求这个,但我不妨补充一下。
要检查一下,将数字 n 向右移动,然后按位移动它:
bit = (number >> n) & 1U;
这会将第n
位数的number
放入变量bit
。
将第n
位设置为1
或0
可以通过以下 2 的补码 C ++ 实现来实现:
number ^= (-x ^ number) & (1UL << n);
如果x
为1
,则设置位n
,如果x
为0
,则清除位n
。如果x
有其他值,你会得到垃圾。 x = !!x
将其布尔化为 0 或 1。
为了使其独立于 2 的补码否定行为(其中-1
设置了所有位,与 1 的补码或符号 / 幅度 C ++ 实现不同),使用无符号否定。
number ^= (-(unsigned long)x ^ number) & (1UL << n);
要么
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
使用无符号类型进行便携式位操作通常是个好主意。
一般来说,通常不要复制 / 粘贴代码也是一个好主意,因此很多人使用预处理器宏(如社区维基回答更进一步 )或某种封装。
使用标准 C ++ 库: std::bitset<N>
。
或Boost版本: boost::dynamic_bitset
。
没有必要自己动手:
#include <bitset>
#include <iostream>
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
与标准库编译时大小的 bitset 相比,Boost 版本允许运行时大小的 bitset。
另一种选择是使用位字段:
struct bits {
unsigned int a:1;
unsigned int b:1;
unsigned int c:1;
};
struct bits mybits;
定义一个 3 位字段(实际上,它是三个 1 位字符)。位操作现在变得有点(哈哈)更简单:
设置或清除一下:
mybits.b = 1;
mybits.c = 0;
要切换一下:
mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1; /* all work */
检查一下:
if (mybits.c) //if mybits.c is non zero the next line below will execute
这仅适用于固定大小的位字段。否则你必须采用之前帖子中描述的比特技巧。