Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get nth bit values

Im relatievly new to the whole bit shifting, and 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 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.

what is the most elegant way to do it?

like image 829
user1930254 Avatar asked Dec 10 '14 22:12

user1930254


People also ask

How do you calculate bit value?

To find the number of binary digits (bits) corresponding to any given decimal integer, you could convert the decimal number to binary and count the bits. For example, the two-digit decimal integer 29 converts to the five-digit binary integer 11101.

How do I access a specific bit?

For accessing a specific bit, you can use Shift Operators . If it is always a 1 that you are going to reset, then you could use an & operation. But, if it can also take 0 value, then & operation will fail as 0 & 1 = 0 . You could use | (OR) during that time.


Video Answer


3 Answers

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
};
like image 128
SirDarius Avatar answered Oct 16 '22 19:10

SirDarius


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:

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:

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.

like image 36
DaveS Avatar answered Oct 16 '22 19:10

DaveS


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");
like image 1
chacham15 Avatar answered Oct 16 '22 17:10

chacham15