Example how of bitwise operators can be useful?

They can be performed on int and char types.. but in what scenario would we use them?
They are often used as "flags"; take a char, for example. Eight bits, typically.

00000000

I'm going to use this to carry information in my code. If the first bit is a zero, it means we're in PLAYBACK_MODE. If the first bit is a one, we're in RECORD_MODE.

If the second bit is one, we're operating at 50_FRAMES_PER_SECOND. If the second bit is zero, we're on 25_FRAMES PER SECOND.

So 11000000 means record at 50 frames per second.

10000000 means record at 25 frames per second.

I set these individual bits with bitwise operators, and pass the value as a single char parameter. Maybe I'm really tight on memory, maybe I don't want to have to pass across eight boolean values to every function.

Often, it will be done using defined values in advance for the flags, so the code ends up looking like:

1
2
char mode = ( 50_FRAMES_PER_SECOND | RECORD_MODE);
setNewModeOnHardware(mode);



So that's one use.

-----------------------

Another use is the wide world of "bit twiddling". Modern compilers can do a lot of this for us, but more primitive compilers won't, and I suspect some of the bit twiddles won't be spotted by even modern compilers.

For example, how do you turn a (fairly standard) floating point number into its own negative? You flip the first bit. How do you flip single bits? Bitwise operators. I'd expect a modern compiler to spot that one for you, but that's just an example. Here are many more; https://graphics.stanford.edu/~seander/bithacks.html




Last edited on
So you're using the bits of a char in a very intelligent way.
But I didn't understand how you would set the bits of the char? Or how would you declare the char with bits you want?

Is this more efficient than bool if you had only two ways? I.e either only play_back or record_mode?
Last edited on
But I didn't understand how you would set the bits of the char?


Somewhere else:
1
2
50_FRAMES_PER_SECOND = 1 << 7; // binary 1000000
RECORD_MODE = 1 << 6; // binary 01000000 


Then, using the bitwise or operator |

char mode = ( 50_FRAMES_PER_SECOND | RECORD_MODE);
Last edited on
So using an int would mean you have 32 bits instead of 8? But it's the same thing?
Can the bits used for int and char be higher than 32 and 8 even though you declared them as int and char? Because I read the word "minimum" and I'm not sure if that means that they can be higher..

I know binary 1 is 1 (and 2 is 10 etc).
But how do I know about char's binary representation for characters?


Oh or can you assign decimal value to char type?

And lastly is this more efficient than bool if you were using it for one single if condition. So like (first_bit ? true : false)
Even minutely?

Also is there anyway to directly assign 8bit binary to char instead of having to do bitwise operations? Like you can assign integer to character (because of ASCII values)?

^^^^^^^ Updated ^^^^^^^^^^
Last edited on
But how do I know about char's binary representation for characters?

You look up what number is used to represent each character. http://www.asciitable.com/

Can the bits used for int and char be higher than 32 and 8 even though you declared them as int and char?

If you have a 32 bit value, you can use all 32 bits. You cannot use 33 bits, because the 33rd bit does not exist.
A simple introduction about bit operations:
https://www.youtube.com/watch?v=NLKQEOgBAnw
And lastly is this more efficient than bool if you were using it for one single if condition. So like (first_bit ? true : false)
Even minutely?


As a general rule, no. The CPU reads in whole words. To extract a single bit requires reading the whole word, and then doing something else with it. To read a bool, it's just the whole word.
Guys is there any way to directly assign bool values to a char variable?

Also is there a way to check the bit of a char variable without having to compare it with another char variable?
Nwb wrote:
But how do I know about char's binary representation for characters?
1
2
3
4
5
6
7
8
#include <iostream>
#include <bitset>
using namespace std;

int main()
{
   for ( char c = 'A'; c <= 'Z'; c++ ) cout << c << ": " << bitset<8>( c ) << '\n';
}

A: 01000001
B: 01000010
C: 01000011
D: 01000100
E: 01000101
F: 01000110
G: 01000111
H: 01001000
I: 01001001
J: 01001010
K: 01001011
L: 01001100
M: 01001101
N: 01001110
O: 01001111
P: 01010000
Q: 01010001
R: 01010010
S: 01010011
T: 01010100
U: 01010101
V: 01010110
W: 01010111
X: 01011000
Y: 01011001
Z: 01011010




Nwb wrote:
Also is there a way to check the bit of a char variable without having to compare it with another char variable?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;

bool checkBit( char c, int bit )
{
   return c & ( 1 << bit );
}

int main()
{
   char c = 'A';
   cout << "For character " << c << " the following bits are set:\n";
   for ( int bit = 0; bit < 8; bit++ )
   {
      if ( checkBit( c, bit ) ) cout << bit << '\n';
   }
}


For character A the following bits are set:
0
6




Nwb wrote:
Guys is there any way to directly assign bool values to a char variable?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;

char putBit( char c, int bit )
{
   return c | ( 1 << bit );
}

int main()
{
   char c = 'A';
   int bit = 4;
   cout << "Initial character: " << c << '\n';
   cout << "After setting bit " << bit << " we get: " << putBit( c, bit ) << '\n';
}


Initial character: A
After setting bit 4 we get: Q
Last edited on
sorry guys I'm just reading through some threads and found this quite interesting

I set these individual bits with bitwise operators, and pass the value as a single char parameter. Maybe I'm really tight on memory, maybe I don't want to have to pass across eight boolean values to every function.


is this a real world example? or just an example? if so what library uses this?

thanks


I also hear bit shifting is great for editing values in registers when doing low level programming such as programming micro-controllers

Opening an output filestream; flags indicating, in this example, that it's a binary stream and data is to be appended.
ofs.open ("test.txt", std::ofstream::binary | std::ofstream::app);
http://www.cplusplus.com/reference/fstream/ofstream/open/
Is this a real world example? or just an example? if so what library uses this?

Yeah, it's a real-world example. The search term is bitmask.

You'll see bitmasks used frequently in C libraries, but even in the C++ standard library there are several examples. The page
https://en.cppreference.com/w/cpp/named_req/BitmaskType
Lists some (all?) of them in the standard library, or at least things that are behave like them. Microsoft's Win32 API uses them a lot, as does POSIX and Linux, even in such fundamental system calls like open().
http://man7.org/linux/man-pages/man2/open.2.html

It's a pretty common technique. Contrast it with, for example, std::fopen, which takes a C-string as the mode parameter, presumably because the string is more extensible.
Topic archived. No new replies allowed.