C语言 – 你如何设置,清除和切换一个位?

如何在C / C ++中设置,清除和切换?


设置一下

使用按位OR运算符(|)设置一个位。

number |= 1UL << x;

这将设置一点x

使用1ULLif number宽于unsigned long1UL << x直到评估1UL << x了未定义的行为偏移超过a的宽度之后才会发生促销long。这同样适用于所有其他示例。

清理一下

使用按位AND运算符(&)清除一下。

number &= ~(1UL << x);

那会很清楚x。必须使用按位NOT运算符(~)反转位串,然后运行AND。

切换了一下

XOR运算符(^)可用于切换位。

number ^= 1UL << x;

那将切换位x

检查一下

你没有要求这个,但我不妨补充一下。

要检查一下,将数字x向右移动,然后按位移动它:

bit = (number >> x) & 1U;

这会将bit的值x放入变量中bit

将第n位更改为x

将该n位设置为1或者0可以通过以下2的补码C ++实现来实现:

number ^= (-x ^ number) & (1UL << n);

n,如果将被设置x1,如果清除x0。如果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

这仅适用于固定大小的位字段。否则你必须采用之前帖子中描述的比特技巧。

添加评论

友情链接:蝴蝶教程