Im relatievly new to the whole bit shifting, and c++.
我对整个位移和c ++都很陌生。
Let's say i have an uint8_t 00100100
(36) and i want to check if the 3th bit is set. Here is the code how im doing it now, for only one bit.
假设我有一个uint8_t 00100100(36),我想检查第3位是否已设置。以下是我现在只做一点的代码。
uint8_t x = 36;
if(x&1<<3)
printf("is set");
how can i check if the 3th OR the 6th bit is set? I want to check several combinations of bits like 5th or 7th or 8th.
如何检查第3位或第6位是否已设置?我想检查几个比特组合,如第5或第7或第8。
what is the most elegant way to do it?
最优雅的方式是什么?
3 个解决方案
#1
11
Checking bits by numeric position is one of the correct ways to do so but it makes the code depend on magic numbers, which makes it harder to read and maintain.
通过数字位置检查位是正确的方法之一,但它使代码依赖于幻数,这使得它更难以阅读和维护。
Usually, when checking for bitmasks, there is a goal of checking for some specific flag, let's say a hardware register for example.
通常,在检查位掩码时,有一个目标是检查一些特定的标志,例如硬件寄存器。
Imagine for example that each bit of your integer represents a specific light in your house, and you want to check whether the bathroom and the kitchen are on:
想象一下,例如你的整数中的每一位代表你家中的特定灯光,你想要检查浴室和厨房是否亮着:
enum LightMask {
ENTRANCE = 0x01,
LIVING_ROOM = 0x02,
RESTROOM = 0x04,
KITCHEN = 0x08,
BATHROOM = 0x10,
BEDROOM1 = 0x20,
BEDROOM2 = 0x40,
ATTIC = 0x80
};
uint8_t lightsOn = GetLightsOn();
if (lightsOn & (BATHROOM | KITCHEN)) {
// ...
}
This is elegant, easy to understand and can be modified pretty easily.
这是优雅的,易于理解,可以很容易地修改。
The enum could also be expressed in terms of bit shifting at no cost for the compiler if you want to explicitely use bit positions instead of constants:
如果你想明确地使用位位置而不是常量,那么枚举也可以用编译器的免费位移来表示:
enum LightMask {
ENTRANCE = 1 << 0,
LIVING_ROOM = 1 << 1,
RESTROOM = 1 << 2,
KITCHEN = 1 << 3,
BATHROOM = 1 << 4,
BEDROOM1 = 1 << 5,
BEDROOM2 = 1 << 6,
ATTIC = 1 << 7
};
#2
3
If you don't know which bit position you want to check until runtime, one way is to make a function so you can call it for any nth bit you want to check:
如果您不知道要在运行时检查哪个位位置,一种方法是创建一个函数,以便您可以为要检查的任何第n位调用它:
bool IsBitSet(uint8_t num, int bit)
{
return 1 == ( (num >> bit) & 1);
}
uint8_t x = 37; //00100101
for (int i = 0; i < 8; ++i)
{
if ( IsBitSet(x, i) )
printf("%dth bit is set\n", i);
else
printf("%dth bit not set\n", i);
}
The output would be:
输出将是:
0th bit is set
1th bit is not set
2th bit is set
3th bit is not set
4th bit is not set
5th bit is set
6th bit is not set
7th bit is not set
If I wanted to check whether bit 3 or bit 6 is set:
如果我想检查是否设置了第3位或第6位:
uint8_t x = 36; //00100100
if ( IsBitSet(x, 2) || IsBitSet(x, 5) )
printf("bit 3 and/or bit 6 is set\n");
You could also make this function inline
to possibly increase efficiency.
您还可以使此功能内联,以提高效率。
#3
0
uint8_t x = 36;
if (x & ((1 << 2) | (1 << 5)))
printf("is set");
or if you know hex:
或者如果你知道十六进制:
uint8_t x = 36;
if (x & 0x24)
printf("is set");
#1
11
Checking bits by numeric position is one of the correct ways to do so but it makes the code depend on magic numbers, which makes it harder to read and maintain.
通过数字位置检查位是正确的方法之一,但它使代码依赖于幻数,这使得它更难以阅读和维护。
Usually, when checking for bitmasks, there is a goal of checking for some specific flag, let's say a hardware register for example.
通常,在检查位掩码时,有一个目标是检查一些特定的标志,例如硬件寄存器。
Imagine for example that each bit of your integer represents a specific light in your house, and you want to check whether the bathroom and the kitchen are on:
想象一下,例如你的整数中的每一位代表你家中的特定灯光,你想要检查浴室和厨房是否亮着:
enum LightMask {
ENTRANCE = 0x01,
LIVING_ROOM = 0x02,
RESTROOM = 0x04,
KITCHEN = 0x08,
BATHROOM = 0x10,
BEDROOM1 = 0x20,
BEDROOM2 = 0x40,
ATTIC = 0x80
};
uint8_t lightsOn = GetLightsOn();
if (lightsOn & (BATHROOM | KITCHEN)) {
// ...
}
This is elegant, easy to understand and can be modified pretty easily.
这是优雅的,易于理解,可以很容易地修改。
The enum could also be expressed in terms of bit shifting at no cost for the compiler if you want to explicitely use bit positions instead of constants:
如果你想明确地使用位位置而不是常量,那么枚举也可以用编译器的免费位移来表示:
enum LightMask {
ENTRANCE = 1 << 0,
LIVING_ROOM = 1 << 1,
RESTROOM = 1 << 2,
KITCHEN = 1 << 3,
BATHROOM = 1 << 4,
BEDROOM1 = 1 << 5,
BEDROOM2 = 1 << 6,
ATTIC = 1 << 7
};
#2
3
If you don't know which bit position you want to check until runtime, one way is to make a function so you can call it for any nth bit you want to check:
如果您不知道要在运行时检查哪个位位置,一种方法是创建一个函数,以便您可以为要检查的任何第n位调用它:
bool IsBitSet(uint8_t num, int bit)
{
return 1 == ( (num >> bit) & 1);
}
uint8_t x = 37; //00100101
for (int i = 0; i < 8; ++i)
{
if ( IsBitSet(x, i) )
printf("%dth bit is set\n", i);
else
printf("%dth bit not set\n", i);
}
The output would be:
输出将是:
0th bit is set
1th bit is not set
2th bit is set
3th bit is not set
4th bit is not set
5th bit is set
6th bit is not set
7th bit is not set
If I wanted to check whether bit 3 or bit 6 is set:
如果我想检查是否设置了第3位或第6位:
uint8_t x = 36; //00100100
if ( IsBitSet(x, 2) || IsBitSet(x, 5) )
printf("bit 3 and/or bit 6 is set\n");
You could also make this function inline
to possibly increase efficiency.
您还可以使此功能内联,以提高效率。
#3
0
uint8_t x = 36;
if (x & ((1 << 2) | (1 << 5)))
printf("is set");
or if you know hex:
或者如果你知道十六进制:
uint8_t x = 36;
if (x & 0x24)
printf("is set");