12

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?

4
  • 1
    Possible dup stackoverflow.com/questions/523724/… Commented Dec 10, 2014 at 22:27
  • 2
    Assuming the rightmost bit is the first rather than the zeroth bit, only << 2 to shift the third bit to the 1's place. Commented Dec 10, 2014 at 22:27
  • 1
    Does any of these bits have a specific meaning ? A clean way could be to define named constants linked to the semantic meaning of each bit. Commented Dec 10, 2014 at 22:30
  • 2
    Semantically, (a & b) || (a & c) is equivalent to (a & b) | (a & c) which is algebraically equivalent to a & (b | c). Iow, you can combine your masks by oring them and apply them all at once at the end Commented Dec 10, 2014 at 22:55

3 Answers 3

18

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 }; 
Sign up to request clarification or add additional context in comments.

1 Comment

Though constant bitshift expressions for assigning the enum values could enhance readability, without any disadvantage (because the OP explicitly asks about bitshifting).
4

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.

2 Comments

if you wanted to make a function to do it, this would be the wrong way. it would be better to implement it as a macro so that the compiler can actually do the calculation at compile time instead of at runtime. with function inlining turned on you can potentially alleviate this problem, but it offers no advantage to do it this way.
@chacham15 You are right. I interpretted the question as the OP wanting to check bit positions that are only known at runtime. I'm editting my answer to reflect that.
1
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"); 

2 Comments

0x24 = 36. Is this derived somehow from 3th OR 6th bit?
@user1930254 Yes, (1 << 2) | (1 << 5) is the equivalent of (4) + (32), which is 36.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.