How do i use it in C++ ?
when is it useful to use ?
Please give me an example of a problem where bitmask is used , how it actually works .
Thanks!
- 829
- 2
- 8
- 14
-
3do you have c++11 ? and std::bitset? – dzada Sep 03 '13 at 12:05
-
`std::ios_base::fmtflags`. – James Kanze Sep 03 '13 at 12:06
-
5https://www.google.com/search?q=what+is+a+bitmask – LarryPel Sep 03 '13 at 12:06
-
29Possible duplicate of google. – Maroun Sep 03 '13 at 12:07
-
Related, but not duplicate: [C/C++ check if one bit is set in, i.e. int variable](http://stackoverflow.com/q/523724/45249). Anyway bitmask is used in C, not C++ where `std::bitset` should be prefered. – mouviciel Sep 03 '13 at 12:09
-
@AnimeaAnimea, It's quite possible to use C++11 with Dev. – chris Sep 03 '13 at 12:11
-
how ? sorry i dont know – Animea Animea Sep 03 '13 at 12:13
-
@AnimeaAnimea Try to find out which compiler version you are currently using - perhaps it already supports C++11 – Hulk Sep 03 '13 at 12:24
4 Answers
Briefly bitmask helps to manipulate position of multiple values. There is a good example here ;
Bitflags are a method of storing multiple values, which are not mutually exclusive, in one variable. You've probably seen them before. Each flag is a bit position which can be set on or off. You then have a bunch of bitmasks #defined for each bit position so you can easily manipulate it:
#define LOG_ERRORS 1 // 2^0, bit 0
#define LOG_WARNINGS 2 // 2^1, bit 1
#define LOG_NOTICES 4 // 2^2, bit 2
#define LOG_INCOMING 8 // 2^3, bit 3
#define LOG_OUTGOING 16 // 2^4, bit 4
#define LOG_LOOPBACK 32 // and so on...
// Only 6 flags/bits used, so a char is fine
unsigned char flags;
// initialising the flags
// note that assigning a value will clobber any other flags, so you
// should generally only use the = operator when initialising vars.
flags = LOG_ERRORS;
// sets to 1 i.e. bit 0
//initialising to multiple values with OR (|)
flags = LOG_ERRORS | LOG_WARNINGS | LOG_INCOMING;
// sets to 1 + 2 + 8 i.e. bits 0, 1 and 3
// setting one flag on, leaving the rest untouched
// OR bitmask with the current value
flags |= LOG_INCOMING;
// testing for a flag
// AND with the bitmask before testing with ==
if ((flags & LOG_WARNINGS) == LOG_WARNINGS)
...
// testing for multiple flags
// as above, OR the bitmasks
if ((flags & (LOG_INCOMING | LOG_OUTGOING))
== (LOG_INCOMING | LOG_OUTGOING))
...
// removing a flag, leaving the rest untouched
// AND with the inverse (NOT) of the bitmask
flags &= ~LOG_OUTGOING;
// toggling a flag, leaving the rest untouched
flags ^= LOG_LOOPBACK;
**
WARNING: DO NOT use the equality operator (i.e. bitflags == bitmask) for testing if a flag is set - that expression will only be true if that flag is set and all others are unset. To test for a single flag you need to use & and == :
**
if (flags == LOG_WARNINGS) //DON'T DO THIS
...
if ((flags & LOG_WARNINGS) == LOG_WARNINGS) // The right way
...
if ((flags & (LOG_INCOMING | LOG_OUTGOING)) // Test for multiple flags set
== (LOG_INCOMING | LOG_OUTGOING))
...
You can also search C++ Triks
-
in your example about bitflags, how does it know which bit belongs to which variable? it's position in the byte, or the actual value of the byte turns on and off certain features? – MarcusJ Jun 01 '15 at 19:38
Bit masking is "useful" to use when you want to store (and subsequently extract) different data within a single data value.
An example application I've used before is imagine you were storing colour RGB values in a 16 bit value. So something that looks like this:
RRRR RGGG GGGB BBBB
You could then use bit masking to retrieve the colour components as follows:
const unsigned short redMask = 0xF800;
const unsigned short greenMask = 0x07E0;
const unsigned short blueMask = 0x001F;
unsigned short lightGray = 0x7BEF;
unsigned short redComponent = (lightGray & redMask) >> 11;
unsigned short greenComponent = (lightGray & greenMask) >> 5;
unsigned short blueComponent = (lightGray & blueMask);
- 5,341
- 3
- 36
- 55
-
1I don't understand this, you're saying 0xF800 is basically a group of bits that it's selecting from (aka it's extracting those bits from a set group of bytes by address)? I thought a bitmask was basically a int of the same size as the data (so in this case it would be 48 bits) and the mask was applied overtop, when the values of the mask is 1 the value of the underlying bit shows through, and when it's zero, it doesn't, allowing you to ignore the off bits? and what is the shifting for? – MarcusJ Jun 01 '15 at 19:36
-
@MarcusJ: please refer to the example by goGud below, which provides more detail on bitmasks (i.e. http://stackoverflow.com/questions/18591924/how-to-use-bitmask/18592049#18592049) – a505999 Feb 16 '16 at 18:41
-
1I'm an idiot. I knew what bitmasking was, but I didn't realize that the RGB triple wasn't 8 bits each, causing my confusion. thanks for the help though! :) – MarcusJ Feb 17 '16 at 08:36
-
@MarcusJ: RGB triple can be 8 bit for each channel and normally is. However there are some RGB formats where the channels can be less than 8 bits such as 5, 6, 5 so that RGB can be fitted into 16 bits. – Damian Dixon Aug 21 '17 at 05:46
Let's say I have 32-bit ARGB value with 8-bits per channel. I want to replace the alpha component with another alpha value, such as 0x45
unsigned long alpha = 0x45
unsigned long pixel = 0x12345678;
pixel = ((pixel & 0x00FFFFFF) | (alpha << 24));
The mask turns the top 8 bits to 0, where the old alpha value was. The alpha value is shifted up to the final bit positions it will take, then it is OR-ed into the masked pixel value. The final result is 0x45345678 which is stored into pixel.
- 20,637
- 5
- 51
- 86
Bitmasks are used when you want to encode multiple layers of information in a single number.
So (assuming unix file permissions) if you want to store 3 levels of access restriction (read, write, execute) you could check for each level by checking the corresponding bit.
rwx
---
110
110 in base 2 translates to 6 in base 10.
So you can easily check if someone is allowed to e.g. read the file by and'ing the permission field with the wanted permission.
Pseudocode:
PERM_READ = 4
PERM_WRITE = 2
PERM_EXEC = 1
user_permissions = 6
if ((user_permissions & PERM_READ) == PERM_READ) then
// this will be reached, as 6 & 4 is true
fi
You need a working understanding of binary representation of numbers and logical operators to understand bit fields.
- 31
- 8
- 327
- 5
- 15
-
1Why is 6 & 4 true though? what mathematical operation is actually happening here? – MarcusJ Jun 01 '15 at 19:56
-
1A binary number is either 0 or 1. 4 is `100`, 6 is `110`. To _and_ the numbers, _and_ each binary digit. – Laurie Stearn Jun 17 '17 at 06:39
-
@LaurieStearn bitwise AND of `100` & `110` is `= 100` why is `100` TRUE? – A-Sharabiani Jan 30 '21 at 20:01
-
1@A-Sharabiani: Depends on how it is evaluated. `000` is commonly evaluated as FALSE. If any of the `0` values switch on to `1` then it commonly evaluates as TRUE. – Laurie Stearn Jan 31 '21 at 02:22