# 3.8a — Bit flags and bit masks

Note: This is a tough lesson. If you find yourself stuck, you can safely skip this lesson and come back to it later.

Bit flags

The smallest addressable unit of memory is a byte. Since all variables need to have unique addresses, this means variables must be at least one byte in size.

For most variable types, this is fine. However, for boolean values, this is a bit wasteful. Boolean types only have two states: true (1), or false (0). This only requires one bit to store. However, if a variable must be at least a byte, and a byte is typically 8 bits, that means a boolean is using 1 bit and leaving the other 7 unused.

In the majority of cases, this is fine -- we’re usually not so hard-up for memory that we need to care about 7 wasted bits. However, in some storage-intensive cases, it can be useful to “pack” 8 individual boolean values into a single byte for storage efficiency purposes. This is done by using the bitwise operators to set, clear, and query individual bits in a byte, treating each as a separate boolean value. These individual bits are called bit flags.

Bit counting

When talking about individual bits, we typically count from right to left, starting with 0 (not 1). So given the bit pattern 0000 0111, bits 0 through 2 are 1, and bits 3 through 7 are 0.

So although we are typically used to counting starting with 1, in this lesson we’ll generally count starting from 0.

Defining bit flags in C++14

In order to work with individual bits, we need to have a way to identify the individual bits within a byte, so we can manipulate those bits (turn them on and off). This is typically done by defining a symbolic constant to give a meaningful name to each bit used. The symbolic constant is given a value that represents that bit.

Because C++14 supports binary literals, this is easiest in C++14:

Now we have a set of symbolic constants that represents each bit position. We can use these to manipulate the bits (which we’ll show how to do in just a moment).

Defining bit flags in C++11 or earlier

Because C++11 doesn’t support binary literals, we have to use other methods to set the symbolic constants. There are two good methods for doing this. Less comprehensible, but more common, is to use hexadecimal. If you need a refresher on hexadecimal, please revisit lesson 2.8 -- Literals.

This can be a little hard to read. One way to make it easier is to use the left-shift operator to shift a bit into the proper location:

Using bit flags to manipulate bits

The next thing we need is a variable that we want to manipulate. Typically, we use an unsigned integer of the appropriate size (8 bits, 16 bits, 32 bits, etc… depending on how many options we have).

Variable myflags, defined above, will hold the actual bits that we’ll turn on and off. How do we turns those bits on and off? We use our bit flags (options).

Turning individual bits on

To set a bit (turn on), we use bitwise OR equals (operator |=):

Let’s unpack this one to show how it works in more detail.

myflags |= option4 is the equivalent of myflags = (myflags | option4).

Evaluating the portion between the parenthesis:

```myflags = 0000 0000 (we initialized this to 0)
option4 = 0001 0000
-------------------
result  = 0001 0000
```

So we get myflags = 0001 0000. In other words, we just turned the 4th bit on.

We can also turn on multiple bits at the same time using bitwise OR:

Turning individual bits off

To clear a bit (turn off), we use bitwise AND with an inverse bit pattern:

This works similarly to the above. Let’s say myflags was initially set to 0001 1100 (options 2, 3, and 4 turned on).

myflags &= ~option4; is the equivalent of myflags = (myflags & ~option4).

```myflags  = 0001 1100
~option4 = 1110 1111
--------------------
result   = 0000 1100
```

So 0000 1100 gets assigned back to myflags. In other words, we just turned off bit 4 (and left the other bits alone).

We can turn off multiple bits at the same time:

Flipping individual bits

To toggle a bit state, we use bitwise XOR:

Determining if a bit is on or off

To query a bit state, we use bitwise AND:

Bit flags in real life

In OpenGL (a 3d graphics library), some functions take one or more bit flags as a parameter:

GL_COLOR_BUFFER_BIT and GL_DEPTH_BUFFER_BIT are defined as follows (in gl2.h):

Here’s a less abstract example for a game we might write:

Why are bit flags useful?

Astute readers will note that the above myflags example actually doesn’t save any memory. 8 booleans would normally take 8 bytes. But the above example uses 9 bytes (8 bytes to define the bit flag options, and 1 bytes for the bit flag)! So why would you actually want to use bit flags?

Bit flags are typically used in two cases:

1) When you have many sets of identical bitflags.

Instead of a single myflags variable, consider the case where you have two myflags variables: myflags1 and myflags2, each of which can store 8 options. If you defined these as two separate sets of booleans, you’d need 16 booleans, and thus 16 bytes. However, using bit flags, the memory cost is only 10 (8 bytes to define the options, and 1 byte for each myflags variable). With 100 myflag variables, your memory cost would be 108 bytes instead of 800. The more identical variables you need, the more substantial your memory savings.

Let’s take a look at a more concrete example. Imagine you’re creating a game where there are monsters for the player to fight. When a monster is created, it may be resistant to certain types of attacks (chosen at random). The different type of attacks in the game are: poison, lightning, fire, cold, theft, acid, paralysis, and blindness.

In order to track which types of attacks the monster is resistant to, we can use one boolean value per resistance (per monster). That’s 8 booleans per monster.

With 100 monsters, that would take 800 boolean variables, using 800 bytes of memory.

However, using bit flags:

Using bit flags, we only need one byte to store the resistances for a single monster, plus a one-time setup fee of 8 bytes for the options.

With 100 monsters, that would take 108 bytes total, or approximately 8 times less memory.

For most programs, the amount of memory using bit flags saved is not worth the added complexity. But in programs where there are tens of thousands or even millions of similar objects, using bit flags can reduce memory use substantially. It’s a useful optimization to have in your toolkit if you need it.

2) Imagine you had a function that could take any combination of 32 different options. One way to write that function would be to use 32 individual boolean parameters:

Hopefully you’d give your parameters more descriptive names, but the point here is to show you how obnoxiously long the parameter list is.

Then when you wanted to call the function with options 10 and 32 set to true, you’d have to do so like this:

This is ridiculously difficult to read (is that option 9, 10, or 11 that’s set to true?), and also means you have to remember which parameters corresponds to which option (is setting the edit flag the 9th, 10th, or 11th parameter?) It may also not be very performant, as every function call has to copy 32 booleans from the caller to the function.

Instead, if you defined the function using bit flags like this:

Then you could use bit flags to pass in only the options you wanted:

Not only is this much more readable, it’s likely to be more performant as well, since it only involves 2 operations (one bitwise OR and one parameter copy).

This is one of the reasons OpenGL opted to use bitflag parameters instead of many consecutive booleans.

Also, if you have unused bit flags and need to add options later, you can just define the bit flag. There’s no need to change the function prototype, which is good for backwards compatibility.

An introduction to std::bitset

All of this bit flipping is exhausting, isn’t it? Fortunately, the C++ standard library comes with functionality called std::bitset that helps us manage bit flags.

To create a std::bitset, you need to include the bitset header, and then define a std::bitset variable indicating how many bits are needed. The number of bits must be a compile time constant.

If desired, the bitset can be initialized with an initial set of values:

Note that our initialization value is interpreted as binary. Since we pass in the value 3, the std::bitset will start with the binary value for 3 (0000 0011).

std::bitset provides 4 key functions:

• test() allows us to query whether a bit is a 0 or 1
• set() allows us to turn a bit on (this will do nothing if the bit is already on)
• reset() allows us to turn a bit off (this will do nothing if the bit is already off)
• flip() allows us to flip a bit from a 0 to a 1 or vice versa

Each of these functions takes a bit-position parameter indicating which bit should be operated on. The position of the rightmost bit is 0, increasing with each successive bit to the left. Giving descriptive names to the bit indices can be useful here (either by assigning them to const variables, or using enums, which we’ll introduce in the next chapter).

This prints:

```Bit 4 has value: 1
Bit 5 has value: 0
All the bits: 00010010
```

Note that sending the bitset variable to std::cout prints the value of all the bits in the bitset.

Remember that the initialization value for a bitset is treated as binary, whereas the bitset functions use bit positions!

std::bitset also supports the standard bit operators (operator|, operator&, and operator^), so you can still use those if you wish (they can be useful when setting or querying multiple bits at once).

We recommend using std::bitset instead of doing all the bit operations manually, as bitset is more convenient and less error prone.

The principles for bit flags can be extended to turn on, turn off, toggle, or query multiple bits at once, in a bit single operation. When we bundle individual bits together for the purpose of modifying them as a group, this is called a bit mask.

Let’s take a look at a sample program using bit masks. In the following program, we ask the user to enter a number. We then use a bit mask to keep only the low 4 bits, which we print the value of.

```Enter an integer: 151
The 4 low bits have value: 7
```

151 is 1001 0111 in binary. lowMask is 0000 1111 in 8-bit binary. 1001 0111 & 0000 1111 = 0000 0111, which is 7 decimal.

Although this example is pretty contrived, the important thing to note is that we modified multiple bits in one operation!

An RGBA color example

Now lets take a look at a more complicated example.

Color display devices such as TVs and monitors are composed of millions of pixels, each of which can display a dot of color. The dot of color is composed from three beams of light: one red, one green, and one blue (RGB). By varying the intensity of the colors, any color on the color spectrum can be made. Typically, the amount of R, G, and B for a given pixel is represented by an 8-bit unsigned integer. For example, a red pixel would have R=255, G=0, B=0. A purple pixel would have R=255, G=0, B=255. A medium-grey pixel would have R=127, G=127, B=127.

When assigning color values to a pixel, in addition to R, G, and B, a 4th value called A is often used. “A” stands for “alpha”, and it controls how transparent the color is. If A=0, the color is fully transparent. If A=255, the color is opaque.

R, G, B, and A are normally stored as a single 32-bit integer, with 8 bits used for each component:

 32-bit RGBA value bits 31-24 bits 23-16 bits 15-8 bits 7-0 RRRRRRRR GGGGGGGG BBBBBBBB AAAAAAAA red green blue alpha

The following program asks the user to enter a 32-bit hexadecimal value, and then extracts the 8-bit color values for R, G, B, and A.

This produces the output:

```Enter a 32-bit RGBA color value in hexadecimal (e.g. FF7F3300): FF7F3300
255 of 255 red
127 of 255 green
51 of 255 blue
0 of 255 alpha
```

In the above program, we use a bitwise AND to query the set of 8 bits we’re interested in, and then we right shift them to move them to the range of 0-255 for storage and printing.

Note: RGBA is sometimes stored as ARGB instead, with the alpha channel being stored in the most significant byte rather than the least significant.

Summary

Summarizing how to set, clear, toggle, and query bit flags:

To query bit states, we use bitwise AND:

To set bits (turn on), we use bitwise OR:

To clear bits (turn off), we use bitwise AND with an inverse bit pattern:

To toggle bit states, we use bitwise XOR:

Quiz

1) Given the following program:

1a) Write a line of code to set the article as viewed.
1b) Write a line of code to check if the article was deleted.
1c) Write a line of code to clear the article as a favorite.
1d) Extra credit: why are the following two lines identical?

 3.x -- Chapter 3 comprehensive quiz Index 3.8 -- Bitwise operators

• Louis Cloete

Alex, you write that your lowBits example is a bit contrived, but you can use very similar code to convert a number to hex and print it. Just keep shifting the number >> 4 and mask out the low 4 bits and you construct a hex number from right to left. You can also mask out the top 4 bits of a fixed width int and shift the number << 4 for sizeof(number) times. That would be almost as simple as your example and feel much more like useful code instead of a contrived example

Anyway, it is just a suggestion and you might want to think about how it will affect the understandability of the example for a first time reader with no prior experience if you change it like this.

• Alex

Good idea. This lesson is slated for a rewrite. I'll put this idea in my notes and integrate it when I do the rewrite. Thanks!

After reading this one for few times, I wanned to check did i understood whats been told here.Never did i knew that asking 3 simple question can be so much time consuming.

• I won't go over everything, here's what I found while looking over your code:

* Try limiting your lines to 80 characters in length to prevent your code from being wrapped on small displays. Most editors have an option to display a vertical line at a specific character count.
* Don't assume a specific integer width. Use one of the types introduced in lesson 2.4a.
* Line 57: @input is unused after this line. Don't modify it.
* @setDifficulty: The following gets the job done too. Only do this if you know that the difficulty bits are successive.

* Repetitive code is bad. You'll learn how to avoid it later on.
* Line 322-325: int & int = int. Make sure you followed lesson 0.11.
* Line 368: Only use the conditional operator if you need the result.
* Line 383: There's no reason to use 3 zeroes.

• Shelton

Hi,
I want to know the best practice to test the bit flag. Is there an elegant way to avoid use lots of if and else in the code?

Thanks!

• Hi Shelton!

Most of the code can be reduced after loops and arrays have been taught.
OP did a lot of unnecessary checks, eg. line 238 to 249 and 328 to 331. He's comparing values again although they didn't change. This can be avoided and save some code and/or improve visibility.
If you post a specific example with lots of ifs that isn't as long as OP's, I might be able to help you better.

• Boteomap2

Error ouput:

i dont know why missing ')'. Help me....

• Boteomap2

oh no...pls ignore this comment. It's my fault, mistake \$ and &...

• There is no \$ operator in C++, you meant &

• Rai

I tried creating a small RPG with char
main.cpp

defence.h

issue is that when converting the pHP of 0x100 to an integer with static_cast, it reads it as 0 instead of 100.

Also wondering how to do the following:
I tried creating a attack.h with

With this the player chooses which attack they want and it takes health away from the monsterHP. But how do I make it so that the Monster randomly chooses one of the char from namespace defence when defending and when attacking it randomly chooses a char from namespace attack. And this would correspond to taking away the char value from pHP and also monsterHP when the player attacks.

Also I tried with a while loop for the player to take turn in attacking and defending until either the monster or player HP reaches from 0x100 to 0. I couldn't get it to work.

Sorry if this is too much to ask, but I feel like this can be possible with what learnt so far. I was just wondering on how to do this. Any help would be appreciated.

• Hi Rai!

> converting the pHP of 0x100 to an integer with static_cast, it reads it as 0 instead of 100
@pHP never is 0x100, because an unsigned char cannot hold 0x100. The maximum value is 0xFF (or 255). Your compiler should've printed a warning.

> how do I make it so that the Monster randomly chooses one of the char from namespace
You can't. A namespace only helps you to organize your code, it doesn't have any functionality. You need to store the attack types in an array (Covered later).

> Also I tried with a while loop for the player to take turn in attacking and defending
Please share your code and describe what exactly is supposed to happen and what is actually happening.

> I feel like this can be possible with what learnt so far
Loops haven't been covered yet, so no. But as long as this doesn't make you skip lessons there's no problem with pre-reading lessons.

> Sorry if this is too much to ask
No whackers. Projects like these keep you going. Learning a new language without using it for something you like is boring.

• Christina

I have included the bitset standard header. Successfully compiled the following :

std::bitset<8> bits(0x2); // we need 8 bits, start with bit pattern 0000 0010
bits.set(option4); // set bit 4 to 1 (now we have 0001 0010)
bits.flip(option5); // flip bit 5 (now we have 0011 0010)
bits.reset(option5); // set bit 5 back to 0 (now we have 0001 0010)

but while executing this piece of code , i get the unhandled exception error
The thread 0xd5c has exited with code 0 (0x0).
Exception thrown at 0x75975EF8 in Project3.exe: Microsoft C++ exception: std::out_of_range at memory location 0x00FDF900.

• Alex

That's odd. Works for me both on Visual Studio and an online compiler. Anybody else having issues here?

• Tested, working. I don't see what would be causing the error. Try debugging your program to see where exactly the exception is being thrown from.

• Christina

I debugged the piece of code.   Just after executing this instruction :
bits.set(option4); // set bit 4 to 1 (now we have 0001 0010).

• Christina

I just found out the issue. Instead of using int option4 i had used unsigned char option4.
I think the bitset functions expect the int data types for the bit opertions.

Now it works fine for me after changing like this:

// const unsigned char option4 = 0x10; // hex for 0001 0000
const int option4 = 4;

Sorry for the confusion.

Thanks

• Alex

Glad you figured it out, and thanks for sharing what went wrong.

• Silviu

My question here is:
When it's testing "if(myflags)" appears on, why ? i know what it means in that condition myflags as long as is different from 0 show this else show this.
When i test it with let's say 1,2,3 will show off, because all this numbers will convert in binary numbers and than compare it.
But why when it's tested like this, shows on , i mean i think it's testing all the numbers in myflags, if i'm not wrong .
Thank you.

• Alex

"if (myflags)" is the same as "if (myflags != 0)".

It shows as on because you turned on option4 before executing this conditional, so myflags != 0.

• Silviu

Yes sorry, i was thinking wrong in the if condition, when it was comparing the digits of the binary numbers. Thank you.

• Liam

Hello,

In the tutorial stated that it is better to use bitset over standard bit operations. But in case of using it for passing flags to functions I cannot figure how that would be practically useful? Since in order to pass to a function multiple flags we still have to do all the bit operations manually and we still have to define all the flags using bits, not integers that would reflect positions and could be used with bitset functions.

• Alex

Good question. std::bitset does have functions and operators that allow you to deal with bitmasks, but as you correctly note, it's a bit awkward that some functions take bit indices and others use bit values. Personally, I'd probably avoid mixing the two, and stick to either using only positions or only values, as appropriate for my program.

• sam

This does not work for me because of the ! outside of the parentheses.

• Because you cannot have an exclamation point there. You can add another pair of parentheses to make it work

• Alex

Typo on my part. Thanks for pointing out the error!

• Dim Tim

You could also note that in embedded programming bit manipulation is essential: microcontrollers use SFR's - special function registers to control peripherals, and most of the SFR's are collection of single bits or groups of bits, performing actions or reflecting status of the peripheral.
BTW, here bit fields in records are also very useful.

P.S.: Thanks for very clear lessons!

• Will

Why use char for

when you can replace char with int, removing the use of the static cast function in

.

Is there some reason why you would use char over int?
Is it because each of the RGBA values are 8 bits (1 byte) each and you are trying to save memory?

• nascardriver

Hi Will!

> Is it because each of the RGBA values are 8 bits (1 byte) each and you are trying to save memory?
Yes

• Inan

Why using a hex valuse while usin decimel also giving same result?

• nascardriver

Hi Inan!

There's no difference. C++ doesn't have the functionality to differentiate between numeric systems.

• Anandkumar

Hi Alex,

In most of the programs const keyword is used, same needs to be changed to constexpr.
Rule: Any variable that should not change values after initialization and whose initializer is known at compile-time should be declared as constexpr.

• Alex

Most of these tutorials were written before constexpr existed. It's not worth the time to go back and constexpr them. I'll make a note of such on the constexpr tutorial.

• nascardriver

If you want me to I can help updating the lessons to use your rules, especially uniform initialization as that's something I point out on the majority on code submissions.

• J Gahr

Using std::bitset, I tried to initialize my variable like this:

I expected it to print 0010 0001 (decimal 33), but it instead printed 0000 0101 (decimal 5). Where did I go wrong?

• nascardriver

Hi J!

The number in your option's names doesn't match their value.
option1 is 0, not 1.
option2 is 1, not 2.
And so on.

• J Gahr

Okay, so when I replaced this:

with this:

I got the result of 33 (00100001) that I was expecting. I was confused by Alex's std::bitset examples.

• Rohit

when you initially had the options equal to 0,1...7, that was in integer form. you need to have them equal binary/hex values. so:

because for option8, you want the bit flag 1000'0000, instead, when you say option8=7, you have 0000'0111, because that's what decimal 7 is in binary form.

also, as nascardriver said, you might want to change the variable names to option0,option1...option7 just for consistency

• Anderson

How this turns an option on?
myflags |= option4
If all options on myflags are off and option4  is off the bits should be:
0000 0000
0000 0000
So OR should also be 0, right? What am I missing?

• nascardriver

Hi Anderson!

option4 isn't off, option4 is 4.

• Anderson

OOOH, the options are only used to data manipulation?
Neat! I was thinking the options were storing the information thenselves :facepalm:

• Alex

Yes, the options are just bit manipulators. I'll make this clearer in the lesson, because it may not be obvious if you're not already familiar with the concept. 🙂

• Anderson

Explain about how they are just manipulators before you show how to create then, I got stuck there and didn't even read the rest... If I had read the whole page first I would have understood! Great tutorial btw 🙂
Edit: Put this example there, just to demonstrate the use of option:
myflags |= option4;
What it actually does is:
myflags = 0000 0000
option4 = 0001 0000
OR result: 0001 0000
So you effectively turned that on.

• nascardriver

You seem to have some trouble with the binary system, a decimal 4 is 0100, not 00010000. 00010000 is 16.

Here's an example of how conversion between binary and decimal works.
Let's say we have the binary number 01010001.
The least significant (last) bit is decimal 1. The next bit is 2, then 4, then 8. Always multiply the previous value by 2 to get the next.
Write down those decimals values and write the binary number beneath.

Whenever there's a 1 in the binary number you take to decimal above and sum it up.
1 + 16 + 64 = 81
So binary 01010001 is decimal 81.

• Rohit

isn't it true that when using bit flags, his option4 would indeed indicate that the 4th bit is turned on? similarly, wouldn't option5 for a bit flag not be 0000 0101, but in fact 0010 0000?

in this case, you wouldn't want to OR

in order to turn on the fifth bit, correct? even though 0010 0000 is 32 in decimal. This is how i understood it, anyway

• nascardriver

No. If option5 is a decimal 5 then it's a binary 0101. If you want a number with only the fifth bit set you can use

• Alex

Good idea. I've tweaked the lesson to do as you suggest. Thanks!

• yogesh brar

What does bits(0x2) do, is it just to initialize the byte? like 0000 0010, if we write

This will initialize the byte as 0000 0001, so this is to initialize I am guessing as I practiced? b'coz I am confused with the 'start' thing which is said in comment.

Another thing is

This is setting the 5th bit as you see but we are saying it as the 4th bit? Please clarify.
Thanks

• nascardriver

Hi yogesh!

"What does bits(0x2) do, is it just to initialize the byte?"
Yes. 0x02 isn't the index here, but the hexadecimal value. 0x02 will set the bit at index 1.

"This is setting the 5th bit as you see but we are saying it as the 4th bit?"
The bit indexes start with 0 at the end of the string representation of the bitset.

• yogesh brar

Thanks. Got it in the first place, I think I am asking other thing:
Let's say -

Let me explain what I am getting from the 1st line of code till the last line I have written above; if you run this code it sets the byte size of 8 bits which we want to use which is binary 1(0000 0001)[using bits(0x1), then we set (means turn on) the 4th bit(option5) to 1 from 0.

3rd Line of Code prints all the bits like:

4th Line of Code says:

If you see the output here it says: Bit 4 has a value, but if we count the bits from the right it is 5th bit in the output module. This is my doubt with full explanation. Do rectify me where I am wrong; I know I am not right most of the time. But just wanted to ask.
Thanks

• nascardriver

"count the bits from the left"
You count bits starting from the right, not left.

• yogesh brar

I think we count the bits from left.
Counting the bits from right is what it is giving me the 5th bit. Right?

• nascardriver

0001
Bit at index 0 is set

0010
Bit at index 1 is set

0100
Bit at index 2 is set

1000
Bit at index 3 is set

• yogesh brar

Okay. If you checked the output of the

it is:

See the fourth bit is not set. It is the 5th bit from the right and 4th from the left which is set.
I just set the 2nd bit using:

It was 2nd bit from the right which I am counting but 4th bit is a bit confusing, but I will try to give every shot to check it on my end to learn more about it.
Thanks.

• nascardriver

I think you're being confused by the option names,
option5 is bit index 4
option2 is bit index 1

• Alex

In light of this conversation, I've:
* Changed the option names from option1 through option8 to option0 through option7. This is slightly less intuitive for naming options, but aligns the option names with the bit numbers, which is probably an overall win.

• RryanT

Questions about coding that I've done:

Thx for these tutorials, its helping me a lot

• Will

So if I need 32 options as the example, I would have to do like this std::bitset<32> bits; ?
And then add all the options from 1 to 32?

• nascardriver

Hi Will!
You're right. If you actually need 32 options then you'll need to declare 32 options.
Mind sharing what you need that many options for? There might be more convenient ways to handle them than a bitset.

• Will

Nothing really, I was just confused due to the 8 bit thing, I thought this was the limit and then I'd need to go for another of 8, etc till the 32.
Thanks for the info 🙂

• Gavin

I'm trying to program a text based version of Yahtzee for practice. It isn't finished, but my goal is to have it reroll dice if they're considered "Not held". However, when I tried to use this:

it gave me an error message saying that it expected the parenthesis first. Can you tell me what I'm doing wrong? The code is below.

• nascardriver

Hi Gavin!
The syntax of an if-statement is as follows

where 'x' is a boolean expression.
Your exclamation marks are in between the 'if' and the '(', where there's not allowed to be anything but whitespace. The correct place to apply the negation is inside the brackets.

• Gavin

Ah, it's working now. Thanks!

• wayne

Hi Alex,

I thought I would revisit question 6 from section 3.7 and do it using what I have learnt in sections 3.8 and 3.8a. So here goes nothing 😉 I think my code my be a little inelegant, but I just wanted to play around with the concept of bit flags (which I find very cool). I don't really have a question here, just wanted to share my alternative answer to question 6 from section 3.7 here.

``` #include <iostream> #include <bitset> int main() {     const unsigned char bitNum_0 = 1 << 0;  // 0000 0001     const unsigned char bitNum_1 = 1 << 1;  // 0000 0010     const unsigned char bitNum_2 = 1 << 2;  // 0000 0100     const unsigned char bitNum_3 = 1 << 3;  // 0000 1000     const unsigned char bitNum_4 = 1 << 4;  // 0001 0000     const unsigned char bitNum_5 = 1 << 5;  // 0010 0000     const unsigned char bitNum_6 = 1 << 6;  // 0100 0000     const unsigned char bitNum_7 = 1 << 7;  // 1000 0000     unsigned char myByte = 0;         // 0000 0000          std::cout << "Enter an integer between 0 and 255, inclusive: ";     int input;     std::cin >> input;          char num = static_cast<char>(input);          if(bitNum_0 & num)        myByte |= bitNum_0;          if(bitNum_1 & num)        myByte |= bitNum_1;            if(bitNum_2 & num)        myByte |= bitNum_2;            if(bitNum_3 & num)        myByte |= bitNum_3;            if(bitNum_4 & num)        myByte |= bitNum_4;            if(bitNum_5 & num)        myByte |= bitNum_5;            if(bitNum_6 & num)        myByte |= bitNum_6;            if(bitNum_7 & num)        myByte |= bitNum_7;            std::cout << static_cast<int>(myByte) << std::endl;     std::bitset<8> b;     b = myByte;     std::cout << b << std::endl;          return 0; } ```

• Trung

Hi Alex,
Could you show me how to use bitset to set on multiple bits at once? When I try using bitwise OR like bits.set(1|2), it turns to bits.set(3) so that only bit 3 is on. I'm a bit confused here 🙂 Thanks.

• Alex

You can't set multiple bits at once via the set() function. I think the best way to do so might be by using the bitwise assignment operators (&= and |=).

• James

Is this a Monster Hunter reference? 😀

• Alex

Not specifically -- it's more of a reference to roguelike games (which I happen to be fond of). 🙂

• Vishal

I did not understand how if(option4 & myflag) would be a query. I assume the above expression evaluated to true. Can anyone explain me how?

• Alex

This does a bitwise AND of option4 and myflag. If bit option4 in myflag is 0, the if statement won't execute. If it's 1, it will.

• Vishal

Thanks for the reply. But I still have some problems because of lack of bit level programming.Is n’t myflag value 00000000 and hence AND operation of myflag with anything would always evaluate to false (0).

• Alex

If myflag is 0, then yes, the result will always be false.

But what if myflag had bit pattern 0110 1000? Then myflag & option 4 would be:

0110 1000
0000 1000

If you AND those together, you get 0000 10000, which evaluates to boolean true.

• Vishal Sundarrajan

Ah! I got that. 'myflag' is the concerned variable here. I was thinking the other way. My bad. Thx for the explanation

• Liam

In the code mentioned on this page you seem to be using ~ as not, whereas in previous pages you have used ! . What is the difference between the two? Did I miss this somewhere?

• Alex

Logical NOT (!) is typically used for boolean values. It will flip a 0 to a 1, or a non-zero number to a 0.
Bitwise NOT (~) is typically used for bit flags and bit masks. It will flip each individual bit from 0 to 1 or 1 to 0.

• Rich

That 'bit wasteful' joke is a groaner! But I laughed 🙂

• Alex

That wasn't even intentional! Technically, it's 7 bits wasteful. 🙂

• Jan

Hey Alex,

firstoff thank you so much for your great tutorials.

Second, I think in the code above the comments should not state that it is hex. The variables/bitflags are initialized with regular decimal integer literals. There is no 0x before the literal.

• Alex

Agreed, I'd previously updated the literals but missed updating the comments as well. Thanks for pointing out the inconsistency.

• jack

is it ok Alex to use decimal values instead of hex?

• Alex

Yes.

• Angel

Hello Alex, I am quite confused about the following code:

Why do we need to use the left-shift operator here?