Search

O.3 — Bit manipulation with bitwise operators and bit masks

In the previous lesson on bitwise operators (O.2 -- Bitwise operators), we discussed how the various bitwise operators apply logical operators to each bit within the operands. Now that we understand how they function, let’s take a look at how they’re more commonly used.

Bit masks

In order to manipulate individual bits (e.g. turn them on or off), we need some way to identify the specific bits we want to manipulate. Unfortunately, the bitwise operators don’t know how to work with bit positions. Instead they work with bit masks.

A bit mask is a predefined set of bits that is used to select which specific bits will be modified by subsequent operations.

Consider a real-life case where you want to paint a window frame. If you’re not careful, you risk painting not only the window frame, but also the glass itself. You might buy some masking tape and apply it to the glass and any other parts you don’t want painted. Then when you paint, the masking tape blocks the paint from reaching anything you don’t want painted. In the end, only the non-masked parts (the parts you want painted) get painted.

A bit mask essentially performs the same function for bits -- the bit mask blocks the bitwise operators from touching bits we don’t want modified, and allows access to the ones we do want modified.

Let’s first explore how to define some simple bit masks, and then we’ll show you how to use them.

Defining bit masks in C++14

The simplest set of bit masks is to define one bit mask for each bit position. We use 0s to mask out the bits we don’t care about, and 1s to denote the bits we want modified.

Although bit masks can be literals, they’re often defined as symbolic constants so they can be given a meaningful name and easily reused.

Because C++14 supports binary literals, defining these bit masks is easy:

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 masks 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 4.12 -- 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:

Testing a bit (to see if it is on or off)

Now that we have a set of bit masks, we can use these in conjunction with a bit flag variable to manipulate our bit flags.

To determine if a bit is on or off, we use bitwise AND in conjunction with the bit mask for the appropriate bit:

This prints:

bit 0 is on
bit 1 is off

Setting a bit

To set (turn on) a bit, we use bitwise OR equals (operator |=) in conjunction with the bit mask for the appropriate bit:

This prints:

bit 1 is off
bit 1 is on

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

Resetting a bit

To clear a bit (turn off), we use Bitwise AND and Bitwise NOT together:

This prints:

bit 2 is on
bit 2 is off

We can turn off multiple bits at the same time:

Flipping a bit

To toggle a bit state, we use Bitwise XOR:

This prints:

bit 2 is on
bit 2 is off
bit 2 is on

We can flip multiple bits simultaneously:

Bit masks and std::bitset

std::bitset supports the full set of bitwise operators. So even though it’s easier to use the functions (test, set, reset, and flip) to modify individual bits, you can use bitwise operators and bit masks if you want.

Why would you want to? The functions only allow you to modify individual bits. The bitwise operators allow you to modify multiple bits at once.

This prints:

bit 1 is off
bit 2 is on
bit 1 is on
bit 2 is off
bit 1 is on
bit 2 is on
bit 1 is off
bit 2 is off

Making bit masks meaningful

Naming our bit masks “mask1” or “mask2” tells us what bit is being manipulated, but doesn’t give us any indication of what that bit flag is actually being used for.

A best practice is to give your bit masks useful names as a way to document the meaning of your bit flags. Here’s an example from a game we might write:

Here’s the same example implemented using std::bitset:

Two notes here: First, std::bitset doesn’t have a nice function that allows you to query bits using a bit mask. So if you want to use bit masks rather than positional indexes, you’ll have to use Bitwise AND to query bits. Second, we make use of the any() function, which returns true if any bits are set, and false otherwise to see if the bit we queried remains on or off.

When are bit flags most useful?

Astute readers may note that the above examples don’t actually save any memory. 8 booleans would normally take 8 bytes. But the above examples use 9 bytes (8 bytes to define the bit masks, and 1 bytes for the flag variable)!

Bit flags make the most sense when you have many identical flag variables. For example, in the example above, imagine that instead of having one person (me), you had 100. If you used 8 Booleans per person (one for each possible state), you’d use 800 bytes of memory. With bit flags, you’d use 8 bytes for the bit masks, and 100 bytes for the bit flag variables, for a total of 108 bytes of memory -- 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.

There’s another case where bit flags and bit masks can make sense. 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, a well regarded 3d graphic library, opted to use bit flag parameters instead of many consecutive Boolean parameters.

Here’s a sample function call from OpenGL:

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

Bit masks involving multiple bits

Although bit masks often are used to select a single bit, they can also be used to select multiple bits. Lets take a look at a slightly more complicated example where we do this.

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
Your color contains:
ff red
7f green
33 blue
0 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 into an 8-bit value so we can print them back as hex values.

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 bitwise NOT:

To flip bit states, we use bitwise XOR:

Quiz time

Question #1

Given the following program:

a) Write a line of code to set the article as viewed.

Show Solution

b) Write a line of code to check if the article was deleted.

Show Solution

c) Write a line of code to clear the article as a favorite.

Show Solution

1d) Extra credit: why are the following two lines identical?

Show Solution


O.4 -- Converting between binary and decimal
Index
O.2 -- Bitwise operators

260 comments to O.3 — Bit manipulation with bitwise operators and bit masks

  • ronald

    // byte-size value to hold some combination of the above 8 options
    unsigned char myflags = 0; // all options turned off to start

    i am so clueless as to what this is supposed to do??

  • Programer unknown

    // byte-size value to hold some combination of the above 8 options
    unsigned char myflags = 0; // all options turned off to start

    i am so clueless as to what this variable is supposed to do is it the byte that will hold all the flags like as if the flags where a indivisual bits.

  • Renegrade

    This is kinda like stock C stuff - in C though, we typically (or at least, very often) handle them this way:

    Leaving aside differences in how constants are defined, using the left shift operator to define the bits themselves increases readability somewhat and makes iteration a lot simpler, as you can see.  The example could be extended to the full eight bits, but I'm very tired at this point, runnin' out of juice.

    The bits are like 1-bit elements in a byte- (or short/long/whatever) sized array.  1<<0 is the 0th bit (like the 0th element of an array), 1<<1 is the 1st, and so on.

    Doing this in the preprocessor means that it's all pre-computed at compile time.  Care should be taken that any C++ version of this is also pre-computed, but that should be easy enough.

    • Alex

      In C++14, you can actually use binary literals now. I don't do it here because I'm guessing many users still aren't on C++14 compatible compilers. But I'll mention it in the lesson as the better option.

      • Renegrade

        Yeah, my compiler does NOT support the C++14 stuff (gcc 4.4), although it DOES support it's own almost-identical extension (it ONLY lacks the '\'' separator).  Well I also have MSVC 19 ("2015"), which does support it .. so it's a mixed bag for me, at least until I update my main server (really old Debian 6).

        I still prefer the (1<<x) notation for bitflags though.  While 0b0000'1000 is clearer than 0x08, especially re: accidentally setting two or more bits at once (0x60 might look like a single flag to a novice for example, when it's really 0xb0110'0000), I feel that (1<<x) clearly conveys that it's a single bit, and gives it an index number, effectively.

        It's only real caveat is that you might end up with trouble in say, DOS or embedded environments, where int is 16-bit.. that would trip up 0x00 and 0b0000 as well though.  In either case, adding a L or UL to the constant would solve the problem (1L<<x) 0b1010UL, etc.

        It's good though that you're addressing this.  I get blank looks from people when I talk about bitflags these days.  Young punks, get off my lawn!

  • AMG

    Alex,
    About quiz.
    1) Would suggest initialization: 'unsigned char myArticleFlags (0x0);'
    2) Why copy initialization is preferred over direct and uniform initialization. 'unsigned char option_viewed = 0x01;' instead of 'unsigned char option_viewed {0x01};'

    • Alex

      1) Done.
      2) It's not. When initializing fundamental variables, any of the three initialization methods is fine. I tend to use copy initialization just out of habit.

  • JoeyM

    Using C++11 would the following code now be

  • Hardik

    it's output is as follows :-
    1
    2
    4
    8
    16
    32
    64
    128

    Does this signify that the whole byte is occupied instead of alloting each byte to a single char variable(options) ? Have u given each bye to single char option or a single bit has been alloted to each of the char variable?

    • Hardik

      sorry...i meant that it is alloted a single byte to each of the char variable or a whole byte has been alloted to all of the options as a whole using bit flags ?

    • Alex

      Variable "me" is a char, which takes a whole byte. The flags also take an entire byte each. In the above code, you're doing a bitwise AND on "me" and the flag, resulting in a new byte with the appropriate bits set, which is then being interpreted as an integer (since chars are integers)

      • Hardik

        i understood that.Thank You. BUT, Then, How does bit flags save memory ?
        Plz Explain it to Me ! i always get stuck in this chapter....!!!

        • Alex

          If you only have one set of states you're tracking, it doesn't save any memory. In the example above, we end up using 9 bytes (8 bytes to define the bit flags and 1 byte to store them), as opposed to using 8 bytes if we just used a single boolean to store each state.

          However, if you have multiple objects that you need to store states for, then bit flags start yielding benefits. Let's say you want to store a set of states for both yourself and your evil twin. Using booleans, you'd need 2 full sets of booleans (2 x 8 booleans), which would be 16 bytes. However, with bit flags, it would only cost 10 bytes (8 bytes to define the bit flags, and 1 byte per object to store the bits). So we're already seeing savings. Those savings continue to increase with additional objects.

          • Hardik kalra

            But How? Without using bit flags also it would end up using 10 bytes....Cant The Second variable(me1) access the same options as it was accessed by the first variable(me) ?

            And One More Help From You.....
            Plz Define A Set Of Options(Like Above) But, That shouldnt Use Bitflags

            • Alex

              With bit flags, 2 variables (total cost = 10 bytes):

              Without bit flags (total cost = 16 bytes):

              • Hardik kalra

                Thats What I'm asking.....Can't The Second Variable, that is, eviltwinflags access the meisMad Or Any of the options that have been used for "me" !?

                If yes, then see, it will also consume 10bytes only

                And One More Question !
                When i try to print isMad Or Any Option without printing it like (me & isMad), it prints it as an unrecognizable character......Why?

                • Alex

                  > Can’t The Second Variable, that is, eviltwinflags access the meisMad Or Any of the options that have been used for "me" !?

                  Yes, it can. That's why bit flags are useful -- we only need to define the bit flags once, and then we can use them over and over.

                  The bit flags are printing as funny characters because they're printing as chars, and chars with values lower than 32 are "unprintable", so your OS is subbing in some other symbol.

                • Hardik kalra

                  Here, in This Code...
                  false;
                  bool meIsSad = false;
                  bool meIsMad = false;
                  bool meIsHappy = false;
                  bool meIsLaughing = false;
                  bool meIsAsleep = false;
                  bool meIsDead = false;
                  bool meIsCrying = false;

                  bool evilTwinIsHungry = false;
                  bool evilTwinIsSad = false;
                  bool evilTwinIsMad = true;
                  bool evilTwinIsHappy = false;
                  bool evilTwinIsLaughing = false;
                  bool evilTwinIsAsleep = false;
                  bool evilTwinIsDead = false;
                  bool evilTwinIsCrying = false;

                  Can the eviltwinflags access the options that have been used for "me" !? I meant to ask this !

                  For Eg. evil twin flags |= meIsMad | meIsHungry; //initial value of evil twin flags was zero

                  • Alex

                    > Can the eviltwinflags access the options that have been used for "me" !?

                    In the bit flags case, yes. In the boolean case, no.

                    This is fine if meIsMad and meIsHungry are bit flags. This is not fine if they are booleans. The difference is that the bit flags don't actually hold any values -- they're just bit position indicators. So they can be shared. The variable that holds the actual values (for me and my evil twin) needs to be unique, and can't be shared.

                • Hardik

                  Don't you think when we do (myflags & option4) it evaluates to ZERO, so how does it query the bit state, or, here, & is an overloaded operator ?

                  • Alex

                    I'm not sure I understand the question. myflags & option4 causes operator & to evaluate operands myflags and option4 to produce a bitwise result. It may evaluate to zero or non-zero depending on the value of myflags.

                • Hardik

                  And I think all the bitwise operators are overloaded when u use them to turn on, off, toggle or query their state !
                  am I right or not? Plz tell me !

                • Hardik kalra

                  So If I try to assign boolean values to evil twin flags....will it give an error ?

                • Hardik kalra

                  Thats what i meant to say :-
                  bool meIsHungry = false;
                  bool meIsSad = false;
                  bool meIsMad = false;
                  bool meIsHappy = false;
                  bool meIsLaughing = false;
                  bool meIsAsleep = false;
                  bool meIsDead = false;
                  bool meIsCrying = false;

                  bool evilTwinIsHungry = false;
                  bool evilTwinIsSad = false;
                  bool evilTwinIsMad = true;
                  bool evilTwinIsHappy = false;
                  bool evilTwinIsLaughing = false;
                  bool evilTwinIsAsleep = false;
                  bool evilTwinIsDead = false;
                  bool evilTwinIsCrying = false;

                  Inspite of using 2 sets of booleans for two vars we can just use one set for two variables....i aint talking about modifications here

                  Same memory would be saved
                  (8bytes + 2bytes) = 10Bytes would be used

                  • Alex

                    No. Each boolean represents a specific piece of memory that we're using to store a value. That can't be shared between two variables.

              • Hardik kalra

                And If We Try To Use Integers !?

                • Alex

                  Doesn't matter. You seem to be missing some fundamental points, so let me try one last time to see if I can make this clear. From the beginning.

                  In order to store a value (of any type) we need a variable to do so.

                  If order to store 2 values, we need 2 variables:

                  We can't use the same variable to hold two (or more) independent values, because as soon as we assign the variable a second value, it will lose its first value (and vice-versa). We need independent memory locations to hold independent values.

                  Now consider the case where we want to store 8 independent boolean values:

                  Because these need to be separate values, we have to use 8 boolean variables. If we needed two sets of these, we'd need 16 boolean variables.

                  This works, but in the case of bool it's a waste of memory. Because machines tend to be byte-addressable, a bool takes 1 byte (8 bits). But only 1 of those bits is actually used to store true or false -- the 7 bits go to waste.

                  If only there were some way to use those other 7 bits. There is -- bitwise operators. By being clever with the bitwise operators, we can get and set the individual bits in a byte, which allows us to compact 8 unique boolean values into a single byte. For our single byte, we typically use an unsigned char.

                  But in order to do this, we need to be able to identify each bit individually. We typically say a byte is 8 bits, so we can number the bits from left to right: 8 7 6 5 4 3 2 1. Then all we need to do is say: turn bit 5 on, turn bit 4 off, flip the state of bit 2.

                  The bit numbers are reusable because they're just bit positions. The unsigned char needs to be unique so we can store a unique set of 8 bits.

                  Our bit flag variables act as the bit numbers (which is why they are reusable -- they just identify which bit we're talking about, not the value we're trying to get or set). The unsigned char (me or my evil twin) act as the variable that stores a unique set of 8 bits.

                  If you have any minor clarifications needed about this, I'm happy to address. But if you still don't get it, then I'd say move on. This isn't critical to know and it won't block you from proceeding.

                • Hardik kalra

                  So The Conclusion is that we cannot re-assign fundamental data types to two variables but this is not the case with BitFlags.....Ok !

                • Hardik kalra

                  Sorry I Didnt mean to say this...i know that we cannot use one variable to store two values.....this is basic....what i meant to ask is that :-
                  for eg :-
                  bool opt1 = false;
                  bool opt2 = true;

                  bool sopt1 = false;
                  bool sopt2 = true;

                  //Now Lets Declare two char vars :-
                  unsigned char myflags = !opt1;
                  unsigned char eviltwinflags = opt2;

                  See Here There was no requirement to define sopt1&2....that's what i meant to say that why we are declaring two sets of booleans if our work can be done by just using one set......

                  Yes I Agree on one point that we can produce an aggregated result using bitwise operators;
                  For Eg -- myflags |= opt1 | opt2;
                  (opt1 and opt2 are bit flags here).....

                  I Hope Now u have understood my question !

                  • Alex

                    You would never do this. You're mixing metaphors. The top set of 4 booleans is what you'd do without bit flags, since you're using discrete variables to hold values.

                    If you're using bit flags, you need two things: a variable to hold the bits (myflags and eviltwinflags) AND the bit positions. We use symbolic constants to give meaning to the bit flags (e.g. isHappy, because that's more meaningful than 0x4).

                    You'd never use booleans as the bit positions because booleans only hold 2 values (0 and 1), which is 1 bit. If you used booleans as bit flags then you'd have no way to access the other 7 bits in your variable.

  • Jim Smith

    For those of us for whom English is a foreign language it can be a little confusing the sentence "Write a line of code to unset the article as a favorite."

    Searching for the meaning of the verb "to unset". I have found that most reputable online dictionaries don't even recognize this as a verb but only as an adjective with the following meanings:
    a) not fixed in a setting, unmounted (e.g. unset diamonds)
    b) not firmed or solidified (e.g. unset concrete)

    Some sources say that "to unset" means "(label) to make not set" (which is even more confusing). How can I set a bit in such a way as to make it "not set"?

    On the other hand, the verb "TO RESET" has a clear meaning in engineering, "to restore (a gauge, dial, etc) to zero". That meaning was borrowed by Computer Science where it means "clear to restore (the contents of a register or similar device) in a computer system to zero".

    TLDR unset = reset?

    • Alex

      In this context, unset = reset. Reset is a bit ambiguous because it's unclear whether you're resetting to 0 or resetting to the initial state, whatever that was. So "unset" is sometimes used to mean "return to the off state".

      However, in this context, the word "clear" works just as well, so I've replaced "unset" with "clear", which makes it clear(er) we're setting bits back to 0.

  • Dani

    #include <bitset>
    #include <iostream>

    const int option_1 = 0;
    const int option_2 = 1;
    const int option_3 = 2;
    const int option_4 = 3;
    const int option_5 = 4;
    const int option_6 = 5;
    const int option_7 = 6;
    const int option_8 = 7;

    int main()
    {
        std::bitset<8> bits(0x2);
        bits.set(option_5);
        bits.flip(option_6);
        bits.reset(option_6);
        std::cout << "Bit 4 has value: " << bits.test(option_5) << '\n';
        std::cout << "Bit 5 has value: " << bits.test(option_6) << '\n';
        std::cout << "All the bits: " << bits << '\n';
        std::cout << "size of bits  " <<sizeof(bits) ;// _________shows 4 byte ____________//

        return 0;
    }

    i have a question ,i guess that size of "bits"(source code above) will need 1 byte( 8 bits) only,after i compiled the code it shows 4 byte.can you explain me ?Thanks for nice tutorial

    • Alex

      This comes down to how std::bitset is implemented, which may differ from compiler to compiler. But most likely, your version of std::bitset is allocating 32 bits (one word) for anything between 1 and 32 bits for efficiency purposes. This makes the code execute faster at the cost of potentially wasting some memory.

  • 0phoff

    Hey,

    I had some questions about the part where you talk about memory usage.

    Here you write that this code will use 9bytes (8 for options & 1 for the flag itself), but I'm not entirely agreeing with that.
    Because you define the options as being const (and you never use address-of), wouldn't that allow the compiler to inline the values?
    I know the c++ standard doesn't force compilers to inline const statements, but I think most of them do!
    This would mean that, even for situations where you have only a few flags, the way with bits would still take less memory (but more computation time because of the binary operators...)

    Let me know if I am right or not! :)

    • Alex

      Maybe I should say, 9 bytes in the worst case. You're right though, a good compiler would probably inline the const variables, making the code slightly bigger but reducing the memory footprint.

      • 0phoff

        Would the code be bigger though?
        Anyway I am just nitpicking..
        And this could be solved with enums and then there is no discussion! ;)

        • Alex

          Good question, actually. I was thinking about inline functions, which tend to make more code than non-inline functions because the code gets copied into many places instead of staying in a single place. But with literals, at least with fundamental types, this probably isn't true (it might be for more complex types, like classes).

  • Terry

    Hi Alex, how come you use | to specify both options 4 and 5 to turn on, wouldn't it be & because you would be saying option4 AND option 5?

    • Alex

      No. And in fact, bitwise logic tends to be the opposite of how we use terms in common language. In common language we tend to think of OR as a restriction (you can have "A" or "B", you're restricting the choice from a set" and AND as an aggregation (A and B is more than A or B alone).

      In bitwise logic, it's the opposite. OR produces a result that includes all the bits in both operands, so A OR B includes all the bits from both A and B (an aggregation). AND produces a result that includes only the bits in both A or B (a restriction).

      This makes sense when you consider things from a bit by bit level, but it does make it a little hard to wrap your head around the first time.

  • andy mackay

    Just spent half an hour scratching head over the very first example:-

    Testing to see if an option is set using bitwise AND
    if (myflags & option4)

    I was thinking for ages that wouldn't show if option4 was set as it would give 0000 0000, but it just dawned on me that we are testing if myflags has option option4 set and not checking to see if option4 is set, jeez and can be thick sometimes, lol.

  • Victor

    Hello again, Alex.

    Please could you tell us about bit fields - what they are and how to use them? I hope I'm not asking for too much...

    • Alex

      Bit fields allow you to create members of a struct that use less that 1 byte each. This can be useful if you want to compact multiple sub-byte members together to save space. However, with the amount of memory modern machines tend to have, bit fields aren't used near as much these days, so I haven't written a full lesson on them yet. I've added it to my to-do list for the future.

  • Victor

    Hi Alex and thanks again for this great site.

    If one is using std::bitset, is it possible to use typedefs to name custom types rather than having to type out std::bitset<blah> for every declaration, and if so would you consider this good practice?

    Thanks.

    P.S.: How do I get my photo to display in comments :) ?

    • Alex

      Yes, you can use a typedef (or type alias). It's fine to do this if you want.

      To get a photo to display in comments, you need to set up a gravatar with your associated email address. See gravatar.com.

  • James Ray

    Hi Alex,

    After your first example, it may be helpful to post a link to the tutorial on literals. I had to go back as I forgot that hexadecimal counts as 0-9, then A-F in one digit, to go up to 15. I went back because I wanted to check how one digit would go past 9.

  • vishal

    why not just ,me= & isHappy? but me= &~isHappy; I do not understand the purpose of not operator there?

    • Alex

      Turning a bit on is easy -- we just do a logical OR. Turning a bit off is a little more difficult, since C++ doesn't have a logical operator that maps directly to that behavior. So instead, we have to combine two logical operators to get the desired effect.

      Consider the statement me &= ~isHappy. We know isHappy has value 0000 1000, so ~isHappy has value 1111 0111. We don't know what value "me" could have, it could be anything. So let's just say the bits are represented by the letters abcd efgh. Our statement is now abcd efgh &= 1111 0111.

      For any given bit x, if you logical AND x with a 1, x will retain its value. If you logical AND x with a 0, x will be turned off. By using logical NOT on isHappy, we produce exactly the right bit pattern to use with logical AND in order to have all of the bits preserve their original values except the one we want to turn off.

  • Igna

    Typo... you miss the word " a " before "game" in the following statement "Imagine you’re creating game where there are monsters for the player to fight", I think it should be "Imagine you’re creating a game where there are monsters for the player to fight"

    And thanks again for the tutorial...

    PD: Sorry about my English but I speak Spanish

  • Anonymous

    Can the 1a, 1b, 1c questions be solved by using bitset ? And are bitwise operators totally replaceable  with bitset ? Because it'll be great if everything can be done using bitset.

    • Alex

      Yes, quiz questions 1a, 1b, and 1c could be solved that way. Variable myArticleFlags could be a std::bitset and the quiz code should still work (since std::bitset supports bitwise operators).

      However, if you're using std::bitset, you'd want to consider defining the option_xxx values differently (since the bitset functions use indices rather than integer values).

      std::bitset is great, particularly if you want to tweak single bits. It doesn't do quite as well if you need to query or set multiple bits at once.

  • Eric

    Alex,

    You're missing the

    at the bottom of the RGBA color example.

    Thanks for the great work with these tutorials.

  • Karlo

    Hi, Alex! I have a suggestion when turning off bits:

    When you have something like this:

    in case we need to modify more options at once, I found it better to use DeMorgan's law, like this:

    This way you keep the consistency of listing multiple options with | operator like with other actions, and it's slightly more readable. Maybe add that to the lesson? :)

    Also, thank you very much for these lessons. Very well organized, easy to follow, and most important, under constant maintenance and open to suggestions. Keep it up! :)

  • nikos-13

    "  const int option_1 = 0;
    const int option_2 = 1;
    const int option_3 = 2;
    const int option_4 = 3;
    const int option_5 = 4;
    const int option_6 = 5;
    const int option_7 = 6;
    const int option_8 = 7;

    int main()
    {
        std::bitset<8> bits(0x2); // we need 8 bits, start with bit pattern 0000 0010  "

    That means that our first option will be option_2 ?????

  • nikos-13

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

        
    someFunction(option10 | option32); "

    In this case, where we have to define our options? at someFunction or main???

    • Alex

      Good question. In this case, both the caller and callee are going to need access to the options. Probably the best thing to do would be define them at the top of your file (just below the includes) (as global variables, which I cover at the start of chapter 4) or in a header file (which you can then #include).

  • nikos-13

    "
        
    // Define 8 separate flags (these can represent whatever you want)
    // Note: in C++11, better to use "uint8_t" instead of "unsigned char"
    const unsigned char option1 = 0x01; // hex for 0000 0001
    const unsigned char option2 = 0x02; // hex for 0000 0010
    const unsigned char option3 = 0x04; // hex for 0000 0100
    const unsigned char option4 = 0x08; // hex for 0000 1000
    const unsigned char option5 = 0x10; // hex for 0001 0000
    const unsigned char option6 = 0x20; // hex for 0010 0000
    const unsigned char option7 = 0x40; // hex for 0100 0000
    const unsigned char option8 = 0x80; // hex for 1000 0000

    // byte-size value to hold some combination of the above 8 options
    unsigned char myflags = 0; // all flags/options turned off to start

    "

    Could you please show me how to use this in a complete code??? I mean, i understoud how to query,tern on, etc.... but i didn't understand how to define bit flags....

  • Elruin

    In bitset you can also access certain bit by myflags[n], where n is number of bit(from right to left: 0, 1, 2 etc). I think it comes handy in "if" sentences.

  • Mike

    Presumably there is a danger here if a variable is left un-initialised. For example with the quiz, if

    isn't initialised, I run the risk of starting from some random configuration, don't I?

    • Alex

      Yes, absolutely. Presumably you'd want to either initialize myArticleFlags with a value, or assign a value to it shortly after creation.

      I've updated the quiz question to initialize it to 0.

  • Ignacio

    You are amazing man!!! I hope you can do a tutorial like this, but oriented to graphical user interfaces, thanks a lot for this amazing material!!!

  • bert

    Just curious, you say:

    "As a side note, different machine architectures may store bytes in a different order. RGBA can be stored as ARGB or BGRA depending on the architecture."

    What machine architectures would use that byte ordering?  I'm only familiar with big and little endian.  Granted, it's been a while, but those orderings don't strike me as an endian difference.

    tx!

    • Alex

      I think I misspoke -- ARGB is an intentional choice to represent the encoding differently, putting the alpha channel first rather than last. Other permutations (ABGR and BGRA) are the little-endian permutations of RGBA and ARGB.

  • Oliver Dawkins

    Hi, I am thoroughly enjoying these so far, and I'm learning a lot of the finer points of c++ that I didn't at University. In the OpenGL example of bitfalgs, why is there a 4 used in the definition?
    [#define GL_DEPTH_BUFFER_BIT               0x00000100
    #define GL_STENCIL_BUFFER_BIT             0x00000400
    #define GL_COLOR_BUFFER_BIT               0x00004000]
    I'm struggling to figure out how I would manipulate that/ why it is used. I was also under the impression that any positive number is classed as true(1), so I'm stuck there as well and any enlightenment would be appreciated!

    • Alex

      These are hexadecimal numbers (you can tell by the 0x suffix), not binary. A hexadecimal digit is 4 bits (0 hex = 0000 binary, 4 hex = 0100 binary). 8 hexadecimal digits of 4 bits each = 32 bits = 4 bytes.

  • Dawid

    When I check size of (sizeof()) the 8-bits bitflag "bits" (from the example above) i get that it takes 4 bytes. The size of int option_1 is 4 bytes too. Does it mean that I should use fixed width integrers?

    • Alex

      It would make sense to use fixed width integers for the options, but there isn't much that you can do about std::bitset<8> taking 4 bytes.

  • Jonathan

    Is there a way to check that the solutions to the quiz worked correctly? How could I display the state of all the flags at the end of the commands?

    • Alex

      > Is there a way to check that the solutions to the quiz worked correctly?

      Ideally, you'd want to ensure the solutions work with a range of different inputs, and validate that they produce the expected output. You don't necessarily need to print the state of all the flags, but whether that your set of inputs was converted to the set of expected outputs.

      > How could I display the state of all the flags at the end of the commands?

      You can use a for loop and logical AND to isolate and print each individual bit. Something like this:

  • Luis Alonso

    These tutorials are great! I'm super hyped learning about this! Thank you!

Leave a Comment

Put all code inside code tags: [code]your code here[/code]