如何设置特定位?

时间:2013-06-27 05:58:46

标签: c++ bit shift bitset

假设我有一个uint16_t变量,我必须设置特定位。

示例:

uint16_t field = 0;

这意味着这些位都为零:0000 0000 0000 0000

现在我得到了一些我需要在特定位置设置的值。

val1=1; val2=2, val3=0, val4=4, val5=0;

如何设置位的结构如下

0|000|  0000| 0000 000|0

val1应设置在左侧的第一位。所以它只有一个或零。

val2应设置为接下来的三位。接下来的四位val3。接下来的七位是val4,最后一位是val5

结果是这样的: 1010 0000 0000 1000

我只发现了一个特定位而不是“组”。 (移位或bitset)

有谁知道如何解决这个问题?

5 个答案:

答案 0 :(得分:7)

有(至少)两种基本方法。一种方法是创建一个包含一些位域的结构:

struct bits { 
    unsigned a : 1;
    unsigned b : 7;
    unsigned c : 4;
    unsigned d : 3;
    unsigned e : 1;
};

bits b;

b.a = val1;
b.b = val2;
b.c = val3;
b.d = val4;
b.e = val5;

要获取16位值,您可以(例如)使用uint16_t创建该结构的并集。只是一个小问题:当您查看16位值时,标准不保证位字段的结束顺序。例如,您可能需要颠倒我上面给出的顺序,以获得您真正想要的大多数到最低有效位的顺序(但是更改编译器可能会再次搞砸了)。

另一个明显的可能性是使用移位和遮蔽将各个部分组合成一个数字:

int16_t result = val1 | (val2 << 1) | (val3 << 8) | (val4 << 12) | (val5 << 15);

目前,我假设每个输入都在正确的范围内开始(即,具有可以用所选位数表示的值)。如果有可能出错,你首先想要将它掩盖到正确的位数。通常的方法是:

uint16_t result = input & ((1 << num_bits) - 1);

如果你对那里的数学很好奇,它会像这样工作。让我们假设我们要确保输入符合4位。将1向左移位4位会产生00010000(二进制)。从中减去一个然后清除设置的一个位,并设置所有不重要的位,为我们的示例提供00001111。这给我们设置了第一个最低有效位。当我们在输入和输入之间执行逐位AND时,在结果中清除输入中设置的任何更高位。

答案 1 :(得分:1)

其中一个解决方案是设置从field的第N位开始的K位值:

uint16_t value_mask = ((1<<K)-1) << N; // for K=4 and N=3 will be 00..01111000
field = field & ~value_mask; // zeroing according bits inside the field
field = field | ((value << N) & value_mask); // AND with value_mask is for extra safety

或者,如果您可以使用struct而不是uint16_t,则可以使用Bit fields并让编译器为您执行所有这些操作。

答案 2 :(得分:0)

finalvle = 0;
finalvle = (val1&0x01)<<15;
finalvle += (val2&0x07)<<12;
finalvle += (val3&0x0f)<<8
finalvle += (val4&0xfe)<<1;
finalvle += (val5&0x01);

答案 3 :(得分:0)

您可以使用按位或移位运算符来实现此目的。

使用shift <<'向左移动字节':

int i = 1;  // ...0001
int j = i << 3 // ...1000

然后你可以使用按位或|将它放在正确的位置,(假设你在要覆盖的位上都有零)。

int k = 0;  // ...0000
k |= i // ...0001
k |= j // ...1001

编辑:请注意,@ Inspired的答案也解释了将某个区域清零。它总体上解释了如何正确实施它。

答案 4 :(得分:0)

试试这段代码:

uint16_t shift(uint16_t num, int shift)
{
    return num | (int)pow (2, shift);
}

其中shift是你想要设置的位的位置