如何设置、清除和切换一点?


当前回答

int set_nth_bit(int num, int n){    
    return (num | 1 << n);
}

int clear_nth_bit(int num, int n){    
    return (num & ~( 1 << n));
}

int toggle_nth_bit(int num, int n){    
    return num ^ (1 << n);
}

int check_nth_bit(int num, int n){    
    return num & (1 << 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

与标准库编译时大小的位集相比,Boost版本允许运行时大小的比特集。

以下是C中的一个例程,用于执行基本的逐位操作:

#define INT_BIT (unsigned int) (sizeof(unsigned int) * 8U) //number of bits in unsigned int

int main(void)
{
    
    unsigned int k = 5; //k is the bit position; here it is the 5th bit from the LSb (0th bit)
    
    unsigned int regA = 0x00007C7C; //we perform bitwise operations on regA
    
    regA |= (1U << k);    //Set kth bit
    
    regA &= ~(1U << k);   //Clear kth bit
    
    regA ^= (1U << k);    //Toggle kth bit
    
    regA = (regA << k) | regA >> (INT_BIT - k); //Rotate left by k bits
    
    regA = (regA >> k) | regA << (INT_BIT - k); //Rotate right by k bits

    return 0;   
}

比特场方法在嵌入式领域还有其他优势。您可以定义直接映射到特定硬件寄存器中的位的结构。

struct HwRegister {
    unsigned int errorFlag:1;  // one-bit flag field
    unsigned int Mode:3;       // three-bit mode field
    unsigned int StatusCode:4;  // four-bit status code
};

struct HwRegister CR3342_AReg;

您需要注意位打包顺序-我认为它首先是MSB,但这可能取决于实现。此外,验证编译器处理程序字段如何跨越字节边界。

然后,您可以像以前一样读取、写入和测试各个值。

使用此项:

int ToggleNthBit ( unsigned char n, int num )
{
    if(num & (1 << n))
        num &= ~(1 << n);
    else
        num |= (1 << n);

    return num;
}

有时值得使用枚举来命名位:

enum ThingFlags = {
  ThingMask  = 0x0000,
  ThingFlag0 = 1 << 0,
  ThingFlag1 = 1 << 1,
  ThingError = 1 << 8,
}

然后稍后使用这些名称,即写

thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}

设置、清除和测试。通过这种方式,您可以对代码的其余部分隐藏神奇的数字。

除此之外,我支持佩奇·鲁滕的解决方案。