8

我有一个“x”位数的变量。如何提取一组特定的位,然后在 C 中处理它们?

4

4 回答 4

24

您可以使用一系列 2 位逻辑运算来完成此操作。

[[术语 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。我们可以用表达式 '1' 位组成一个位掩码字符串~(~0 << (msb-lsb+1))。例如 ~(~0 << (7-4+1)) == ~0b1111111111111111111111111110000 == 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])

说得通?

快乐黑客!

于 2010-12-11T04:20:32.630 回答
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>在运行时使用然后使用位操作。它的工作量更大,意图比 with 读起来不那么明显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
于 2010-12-11T04:04:01.757 回答
2

使用 &, | 处理位。<<, >> 运算符。例如,如果您的值为 7(整数)并且您想将第二位归零:

7 是 111

(将第 2 位归零并与 101(十进制为 5)相结合)

111 & 101 = 101 (5)

这是代码:

#include <stdio.h>

main ()
{
    int x=7;

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

}

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

于 2010-12-11T06:34:32.717 回答
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 */
于 2010-12-11T08:28:55.783 回答