如何从一个变量中访问特定组的比特?

8

我有一个具有"x"个比特的变量。在C语言中,如何提取特定组的比特并对它们进行操作?


1
你需要更具体一些。你具体想做什么?“处理它们”可以是任何事情。 - EboMike
1
你可能还想澄清一下“提取”的含义。你是想直接修改它们,还是只是获取它们的值并根据结果进行一些计算? - jonmorgan
搜索“位掩码”有助于指引你朝正确的方向前进吗? - momeara
实际上我需要将一个变量中的一组比特与我定义的另一组变量中的比特进行比较。 - user537670
可能是如何在C语言中设置、清除和切换单个位?的重复问题。 - Martin York
4个回答

25
你可以通过两个位运算操作来实现这一点。
[术语 MSB(msb)是最高有效位; LSB(lsb)是最低有效位。假设比特位从lsb == 0到某个msb(例如,在32位机器上为31)。位位置i的值表示整数的2 ^ i分量的系数。]
例如,如果你有一个int x,你想要提取一些范围的位x [msb..lsb],例如x [31..0]位中的4位字段x [7..4],则:
1.通过把x向右移lsb位,例如x >> lsb,您将x的lsb位放在表达式的第0位(最低有效位),这正是它需要的位置。
2.现在,您必须屏蔽掉msb指定的任何剩余位。这样的位数为msb-lsb + 1。我们可以使用表达式 ~(~ 0 <<(msb-lsb + 1))形成长度为1的“1”位掩码字符串。例如: ~(~0<< (7-4+1)) == ~0b11111111111111111111111111110000 == 0b1111.
将所有内容结合起来,您可以使用以下表达式将所需的位向新整数提取出来:
(x >> lsb) & ~(~0 << (msb-lsb+1))
例如,
int x = 0x89ABCDEF;
int msb = 7;
int lsb = 4;
int result = (x >> lsb) & ~(~0 << (msb-lsb+1));
//      ==   0x89ABCDE  & 0xF
//      ==   0xE (which is x[7..4])

听懂了吗?

愉快地进行编程吧!


5

如果你在处理原始数据,那么只需要使用位运算:

int bits = 0x0030;
bool third_bit = bits & 0x0004;  // bits & 00000100
bool fifth_bit = bits & 0x0010;  // bits & 00010000

如果x可以比一个微不足道的基元更大,但在编译时已知,则可以使用std::bitset<>来完成任务:

#include<bitset>
#include<string>

// ...
std::bitset<512> b(std::string("001"));
b.set(2, true);
std::cout << b[1] << ' ' << b[2] << '\n';

std::bitset<32>  bul(0x0010ul);

如果在编译时不知道x的值,那么可以使用std::vector<unsigned char>,然后在运行时使用位操作。虽然工作量更大,意图比std::bitset不够明显且速度较慢,但这可能是在运行时x变化的最佳选择。

#include<vector>

// ...
std::vector<unsigned char> v(256);
v[2] = 1;
bool eighteenth_bit = v[2] & 0x02;  // second bit of third byte

2

使用 &, |, <<, >> 运算符处理位。

例如,如果你有一个值为7(整数),并且想要将第二个位清零:

7 的二进制表示为 111

(将第二个位与 101(十进制中的5)进行 AND 操作)

111 & 101 = 101(5)

以下是代码:

#include <stdio.h>

main ()
{
    int x=7;

    x= x&5;
    printf("x: %d",x);

}

您可以使用其他运算符,如OR、左移、右移等。


0

你可以在联合体中使用位域:

typedef union {
unsigned char value;
struct { unsigned b0:1,b1:1,b2:1,b3:1,b4:1,b5:1,b6:1,b7:1; } b;
struct { unsigned b0:2,b1:2,b2:2,b3:2; } b2;
struct { unsigned b0:4,b1:4; } b4;
} CharBits;


CharBits b={0},a={0};
printf("\n%d",b.value);
b.b.b0=1; printf("\n%d",b.value);
b.b.b1=1; printf("\n%d",b.value);
printf("\n%d",a.value);
a.b4.b1=15; printf("\n%d",a.value); /* <- set the highest 4-bit-group with one statement */

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接