如何设置、清除和切换一点?
当前回答
使用标准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
与标准库编译时大小的位集相比,Boost版本允许运行时大小的比特集。
其他回答
对于初学者,我想用一个例子解释一下:
例子:
value is 0x55;
bitnum : 3rd.
使用&运算符检查位:
0101 0101
&
0000 1000
___________
0000 0000 (mean 0: False). It will work fine if the third bit is 1 (then the answer will be True)
切换或翻转:
0101 0101
^
0000 1000
___________
0101 1101 (Flip the third bit without affecting other bits)
|运算符:设置位
0101 0101
|
0000 1000
___________
0101 1101 (set the third bit without affecting other bits)
该程序基于@Jeremy的上述解决方案。如果有人想快速玩耍。
public class BitwiseOperations {
public static void main(String args[]) {
setABit(0, 4); // set the 4th bit, 0000 -> 1000 [8]
clearABit(16, 5); // clear the 5th bit, 10000 -> 00000 [0]
toggleABit(8, 4); // toggle the 4th bit, 1000 -> 0000 [0]
checkABit(8,4); // check the 4th bit 1000 -> true
}
public static void setABit(int input, int n) {
input = input | ( 1 << n-1);
System.out.println(input);
}
public static void clearABit(int input, int n) {
input = input & ~(1 << n-1);
System.out.println(input);
}
public static void toggleABit(int input, int n) {
input = input ^ (1 << n-1);
System.out.println(input);
}
public static void checkABit(int input, int n) {
boolean isSet = ((input >> n-1) & 1) == 1;
System.out.println(isSet);
}
}
Output :
8
0
0
true
从snip-c.zip的bitops.h:
/*
** Bit set, clear, and test operations
**
** public domain snippet by Bob Stout
*/
typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL;
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
好的,让我们分析一下。。。
在所有这些问题中,您似乎遇到的常见表达是“(1L<<(posn))”。所有这些都是创建一个带有单个位的掩码并且可以与任何整数类型一起工作。“posn”参数指定把钻头放在你想要的位置。如果posn==0,则此表达式将评估为:
0000 0000 0000 0000 0000 0000 0000 0001 binary.
如果posn==8,它将评估为:
0000 0000 0000 0000 0000 0001 0000 0000 binary.
换句话说,它只需在指定的位置唯一棘手的部分是我们需要设置的BitClr()宏1字段中的单个0位。这是通过使用1与颚化符(~)运算符表示的表达式相同的补码。
一旦创建了掩码,它将按照您的建议应用于参数,使用按位和(&)、或(|)和xor(^)运算符。自从面具类型为long,宏将在char、short、int、,或长的。
底线是,这是一个通用的解决方案问题。当然,重写相当于每次使用显式掩码值的任何宏需要一个,但为什么要这样做?请记住,宏替换发生在因此生成的代码将反映以下事实:被编译器认为是常量,即使用起来同样有效每当你需要做的时候,通用宏都会“重新发明轮子”比特操作。
不服气?下面是一些测试代码-我使用了Watcom C,并进行了全面优化并且不使用_cdecl,因此生成的反汇编将与可能:
----[测试.C]----------------------------------------------------------------
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
int bitmanip(int word)
{
word = BitSet(word, 2);
word = BitSet(word, 7);
word = BitClr(word, 3);
word = BitFlp(word, 9);
return word;
}
----[测试输出(拆卸)]-----------------------------------------------
Module: C:\BINK\tst.c
Group: 'DGROUP' CONST,CONST2,_DATA,_BSS
Segment: _TEXT BYTE 00000008 bytes
0000 0c 84 bitmanip_ or al,84H ; set bits 2 and 7
0002 80 f4 02 xor ah,02H ; flip bit 9 of EAX (bit 1 of AH)
0005 24 f7 and al,0f7H
0007 c3 ret
No disassembly errors
----[完成]-----------------------------------------------------------------
此程序用于将任何数据位从0更改为1或从1更改为0:
{
unsigned int data = 0x000000F0;
int bitpos = 4;
int bitvalue = 1;
unsigned int bit = data;
bit = (bit>>bitpos)&0x00000001;
int invbitvalue = 0x00000001&(~bitvalue);
printf("%x\n",bit);
if (bitvalue == 0)
{
if (bit == 0)
printf("%x\n", data);
else
{
data = (data^(invbitvalue<<bitpos));
printf("%x\n", data);
}
}
else
{
if (bit == 1)
printf("elseif %x\n", data);
else
{
data = (data|(bitvalue<<bitpos));
printf("else %x\n", data);
}
}
}
展开位集答案:
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
int main() {
bitset<8> byte(std::string("10010011");
// Set Bit
byte.set(3); // 10010111
// Clear Bit
byte.reset(2); // 10010101
// Toggle Bit
byte.flip(7); // 00010101
cout << byte << endl;
return 0;
}