This is a C++ question on something that is confusing me. (I am refreshing my C++ after a long time). I am reading this example here. There are two parts that confuse me:
The first part:
In the code line:
void namedWindow(const string& winname, int flags=WINDOW_AUTOSIZE )
WINDOW_AUTOSIZE is an input, but as far as I can tell, it is not an int. When I code this line up and run, it works fine. My input into this function literally is 'WINDOW_AUTOSIZE'. I am confused as to why this works. How is WINDOW_AUTOSIZE an int?
My second question is regarding the last line, whereby they say:
By default, flags == CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO |
CV_GUI_EXPANDED
I am confused as to how/what this means exactly... I know that | is a bitwise OR, but not clear what this means exactly...
Thank you.
The words written in capital letters are constants. They have been defined somewhere in the code or in the headers to be used in another place. A constant can stand for a number, string etc. The constants in this code are obviously of the type int
CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED is just bitwise OR of the int values the constants stand for. These are spacial constants where only one bit of the int is set (so called flags)
Assume, CV_WINDOW_AUTOSIZE is 0x1 and CV_WINDOW_KEEPRATIO is 0x2. So bitwise OR-ing would result in 0x3. The called function can then check by AND-operation which flag was set.
My input into this function literally is 'WINDOW_AUTOSIZE'
Yep, WINDOW_AUTOSIZE is in fact an integer; Simply look at the fact that it's a default argument for an int function parameter. It wouldn't compile if it wasn't an int
// it might have been defined like this
#define WINDOW_AUTOSIZE 23434 // some number just for example
// or like this
const int WINDOW_AUTOSIZE = 34234;
As for the second question bitwise ORing means that all bits in the corresponding integral values are ORed together, so lets say for example
CV_WINDOW_AUTOSIZE = 0x0010
CV_WINDOW_KEEPRATIO = 0x0100
CV_GUI_EXPANDED = 0x1100
then the corresponding operation would give an integral value with every bit equal to the result of OR for each position
CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED =
0x0010
0x0100
0x1100
------
0x1110
On the use of bitflags
Consider the following : You have a keyboard with 4 keys :
Ctrl, Alt, Del, Shift
How many constants would you need to define all states this keyboard can be on ? Well lets enumerate the states
All 4 keys pressed : 1 constant
3 keys pressed : It takes (4 by 3) constants = 4 constants :
(4 by 3) = 4! / ( (4-3)! * 3! ) = 4
2 keys pressed : (4 by 2) = 6 constants
1 key pressed : 4 constants (the names of the keys)
No key pressed : 1 constant
So to sum up you'd define :
1 + 4 + 6 + 4 + 1 = 16 constants
Now what if I told you only need 4 different constants, each one having only one bit ON ? :
#define CtrlK 0x0001
#define AltK 0x0010
#define DelK 0x0100
#define ShiftK 0x1000
Then any state for the keyboard can be expressed by a combination of the above : Say you want to express the state Shift key and Del key are pressed. Then it would be
CtrlK | DelK
The more combinations you have, the more this technique pays off.
Ofcourse (maybe you could see a reference on bitflags) user code can probe an integral value to see which bits are switched ON.
I belive the WINDOW_AUTOSIZE is not a string or text. It will be a constant or #defined preprocessor constant. So int datatype can accept it. Please check the definition of the WINDOW_AUTOSIZE in the source code.
Also note that we can pass variables with 'char', 'enum' datatypes to a function which accepts int. The conversion to int will happen internally.
Related
This question already has answers here:
Can I use a binary literal in C or C++?
(24 answers)
Closed 3 years ago.
I have a small question I hope there is a simple answer there. When programming an Arduino in C/C++ the line "DDRB |= 0b00101000;" occurs. While I know DDRB is the Data Direction Register for port B and the meaning of the numbers after "0b00" (which are the slots 13 to 9), I still don't really know what "0b00" means.
In definitions I only read it means HIGH (while 0b11 means LOW) but what does that mean?
Full code:
#include <avr/io.h>
#include <util/delay.h>
int main (void) {
float seconds = 0.5;
int time = 1000 * seconds;
DDRB |= 0b00101000;
while (1) {
PORTB |= 0b00001000;
_delay_ms(time);
PORTB &= 0b11110111;
PORTB |= 0b00100000;
_delay_ms(time);
PORTB &= 0b11011111;
}
return 0;
}
0b means that a number in binary representation is expected.
For Data direction registers, setting the bits to 1 will make the respective lines outputs, and setting to 0 will make them inputs.
The DDRB |= 0b00101000 will do a binary OR operation between the current value of the bits in DDRB with the mask.
This will result in DDRB = 0b××1×1xxx, so that means DDRB will keep the value for lines 7 and 6. This operation basically sets lines 5 and 3 as Output and leaves the rest as they were.
As you tag your question "Arduino", you might be interested that besides the standard c++ 0b... notation the IDE also provides all 8-bit combinations of binary numbers in B00101000 format, with and without leading zeros.
Usually, hex notation (0x28 in your example) is even easier readable, IMO
The line
DDRB |= 0b00101000
basically does a bitwise OR with the mask 0b00101000 and reassigns the results to DDRB.
0b indicates that whatever comes next should be interpreted as binary, so it's easier to see which bits you are masking.
The code is just setting the bits masked as 1 to HIGH and leaving the others unchanged.
I am working on a micro-controller and I want to implement a simple average filter on the resulted values to filter out noise (or to be honest to not let values dance on LCD!).
The ADC result is inserted into memory by DMA. I have (just for sake of ease of debugging) an array with size 8. To make life even easier I have wrote some defines to make my code editable with minimum effort:
#define FP_ID_POT_0 0 //identifier for POT_0
#define FP_ID_POT_1 1 //identifier for POT_1
#define FP_ANALOGS_BUFFER_SIZE 8 //buffer size for filtering ADC vals
#define FP_ANALOGS_COUNT 2 // we have now 2 analog axis
#define FP_FILTER_ELEMENT_COUNT FP_ANALOGS_BUFFER_SIZE / FP_ANALOGS_COUNT
//means that the DMA buffer will have 4 results for each ADC
So, the buffer has size of 8 and its type is uint32_t. And I am reading 2 ADC channels. in the buffer I will have 4 result for Channel A and 4 result for Channel B (in a circular manner). A simple dump of this array is like:
INDEX 0 1 2 3 4 5 6 7
CHNL A B A B A B A B
VALUE 4017 62 4032 67 4035 64 4029 63
It means that the DMA puts results for ChA and ChB always in a fixed place.
Now to calculate the average for each channel I have the function below:
uint32_t filter_pots(uint8_t which) {
uint32_t sum = 0;
uint8_t i = which;
for( ; i < FP_ANALOGS_BUFFER_SIZE; i += FP_ANALOGS_COUNT) {
sum += adc_vals[i];
}
return sum / (uint32_t)FP_FILTER_ELEMENT_COUNT;
}
If I want to use the function for chA I will pass 0 as argument to the funtion. If I want chB I pass 1...and if I happen to have chC I will pass 2 and so on. This way I can initiate the for-loop to point to the element that I need.
The problem is, at the last step when I want to return the result, I do not get the correct value. The function returns 1007 when used for chA and 16 when used for chB. I am pretty sure that the sum is calculated OK (I can see it in debugger). The problem, I beleive, is in the division by a value defined using #define. Even casting it to uint32_t does not help. The sum is being calculated OK, but I can no see what type or value FP_FILTER_ELEMENT_COUNT has been assigned to by compiler. Mybe its an overflow problem of dividing uint32 by uint8?
#define FP_FILTER_ELEMENT_COUNT FP_ANALOGS_BUFFER_SIZE / FP_ANALOGS_COUNT
//means FP_FILTER_ELEMENT_COUNT will be 8 / 2 which results in 4
What causes this behaviour and if there is no way that #define would work in my case, what other options I have?
The compiler is IAR Embedded Workbench. Platform is STM32F103
For fewer surprises, always put parenthesis around your macro definitions
#define FP_FILTER_ELEMENT_COUNT (FP_ANALOGS_BUFFER_SIZE / FP_ANALOGS_COUNT)
This prevents oddball operator precedence issues and other unexpected syntax and logic errors from cropping up. In this case, you're returning sum/8/2 (i.e. sum/16) when you want to return sum/4.
Parentheses will help, as #Russ said, but an even better solution is to use constants:
static const int FP_ID_POT_0 = 0; //identifier for POT_0
static const int FP_ID_POT_1 = 1; //identifier for POT_1
static const int FP_ANALOGS_BUFFER_SIZE = 8; //buffer size for filtering ADC vals
static const int FP_ANALOGS_COUNT = 2; // we have now 2 analog axis
static const int FP_FILTER_ELEMENT_COUNT = FP_ANALOGS_BUFFER_SIZE / FP_ANALOGS_COUNT;
In C++, all of these are compile-time integral constant expressions, and can be used as array bounds, case labels, template arguments, etc. But unlike macros, they respect namespaces, are type-safe, and act like real values, not text substitution.
If we open a file for reading, we may define one or more state flags,
for example: ios::out as well as ios::out | iso::app
I read about the bitwise OR, and how it "merges" the two bit sets,
for example: 1010 | 0111 = 1111
now that being said, I do not understand how it works "behind the scenes" when we use a method like ifstream.open(filename, stateflagA | stateflagB | stateflagC) and so on.
Can someone elaborate more on the inner workings of these state flags and their memory representation?
EDIT:
To give more emphasis on what i am trying to understand (if it helps),
I would assume that the open method could receive one or more state flags as separate arguments in the signature, and not delimited by a bitwise OR, so i want to understand how the bitwise OR works on these state flags to produce a different final state when combining several flags, and as a result allows me to use only one argument for a state flag or a set of state flags.
ie:
ifstream.open(filename, stateflagA | stateflagB | stateflagC)
and NOT
ifstream.open(filename, stateflagA , stateflagB , stateflagC)
Bit flags are represented in the same exact way all integral values are represented. What makes them "flags" is your program's interpretation of their values.
Bit flags are used for compact representation of small sets of values. Each value is assigned a bit index. All integer numbers with the bit at that index set to 1 are interpreted as sets that include the corresponding member.
Consider a small example: let's say we need to represent a set of three colors - red, green, and blue. We assign red an index of zero, green and index of 1, and blue an index of two. This corresponds to the following representation:
BINARY DECIMAL COLOR
------ ------- -----
001 1 Red
010 2 Green
100 4 Blue
Note that each flag is a power of two. That's the property of binary numbers that have a single bit set to 1. Here is how it would look in C++:
enum Color {
Red = 1 << 0
, Green = 1 << 1
, Blue = 1 << 2
};
1 << n is the standard way of constructing an integer with a single bit at position n set to 1.
With this representation in hand we can construct sets that have any combination of these colors:
BINARY DECIMAL COLOR
------ ------- -----
001 1 Red
010 2 Green
011 3 Red+Green
100 4 Blue
101 5 Blue+Red
110 6 Blue+Green
111 7 Blue+Green+Red
Here is when bit operations come into play: we can use them to construct sets and check membership in a single operation.
For example, we can construct a set of Red and Blue with an | like this:
Color purple = Red | Blue;
Behind the scenes, all this does is assigning 5 to purple, because 4 | 1 is 5. But since your program interprets 5 as a set of two colors, the meaning of that 5 is not the same as that of an integer 5 that represents, say, the number of things in a bag.
You can check if a set has a particular member by applying & to it:
if (purple & Red) {
// returns true
}
if (purple & Green) {
// returns false
}
The flags used by I/O library work in the same way. Some of the flags are combined to produce bit masks. They work in the same way as individual flags, but instead of letting you find membership they let you find set intersection in a single bit operation:
Color yellow = Blue | Green;
Color purple = Red | Blue;
Color common = yellow & purple; // common == Blue
If we take the GNU libstdc++ implementation and look at how these are actually implemented, we find:
enum _Ios_Openmode
{
_S_app = 1L << 0,
_S_ate = 1L << 1,
_S_bin = 1L << 2,
_S_in = 1L << 3,
_S_out = 1L << 4,
_S_trunc = 1L << 5,
_S_ios_openmode_end = 1L << 16
};
These values are then used as this:
typedef _Ios_Openmode openmode;
static const openmode app = _S_app;
/// Open and seek to end immediately after opening.
static const openmode ate = _S_ate;
/// Perform input and output in binary mode (as opposed to text mode).
/// This is probably not what you think it is; see
/// http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch27s02.html
static const openmode binary = _S_bin;
/// Open for input. Default for #c ifstream and fstream.
static const openmode in = _S_in;
/// Open for output. Default for #c ofstream and fstream.
static const openmode out = _S_out;
/// Open for input. Default for #c ofstream.
static const openmode trunc = _S_trunc;
Since the values are chosen as 1 << n, they are exactly one "bit" each, which allows us to combine then using | (or) - as well as other similar operations.
So app in binary is 0000 0001 and bin is 0000 0100, so if we do app | bin as a mode for opening the file, we get 0000 0101. The internals of the impplementation of fstream can then use
if (mode & bin) ... do stuff for binary file ...
and
if (mode & app) ... do stuff for appending to the file ...
Other C++ library implementations may choose a different set of bit values for each flag, but will use a similar system.
"Behind the scene", in the memory of the computer every information is ultimately coded as a group of bits. Your CPU is wired to perform basic binary algebra operations (AND, OR, XOR, NOT) on such elementary information.
C++ operators | & and ^ just give direct access to these CPU operations on any integral types. For flag management it's wise to use an unsigned integral type such as unsigned int or unsigned char.
An express overview:
the trick is that every flag corresponds to a fixed bit. This is usually done with a power of 2 constant (ex: 1,2,4,8 which are binary coded as 0001,0010, 0100 and 1000).
constants are named because it's clearer than using litterals (ex: const unsigned FlagA=1, FlagB=2, FlagC=4;)
binary AND x & y ensures that only bits that are 1 in both x and y remain 1. So this is used to reset flags by "anding" with a value where the flag is 0. So x & FlagB reset all flags exept flag B
binary OR x | y any bits that are 1 either in x or y become 1. So it's used to set flags. Example: x | FlagB sets the flag B.
a binary AND is also a quick way to check if a flag is set: (x & FlagB) will be true if and only if the flag B was set.
EDIT: About your specific question on ifstream::open() parameters: it's a design choice, for convenience. As you can see there are 6 flags that influence the way the file is handled (some of them being used very rarely). So instead of providing each of the 6 flags every time, the standard decide that you'd provide them combined in an openmode. Variable number of arguments would not have been an alternative, as the called function would have to know how many arguments you've provided.
First I am not sure what is going on in this bitwise operation.
I get code written and supply to other parties as code snippets.
Now if VAR is unsigned 8bit integer (unsigned char) and r is either 0 or 1 or 2 or 4.
Can following be reversed if the value of r is known and resulting value is there.
VAR |= 1 << r; //that is 200 where VAR was 192 and r was 3
For example initial value of VAR is 192 and value of r is 3 *result is 200*.
Now if I have this 200, and I know the value of r that was 3, can I reverse it back to 192 ?
I hope it is most easy one, but I don't know these bitwise operations, so forgive me.
Thanks
The answer is no. This is because the | (OR) operator is not a one-to-one function.
In other words, there are multiple values of VAR that can produce the same result.
For example:
r = 3;
var0 = 8;
var1 = 0;
var0 |= 1 << r; // produces 8
var1 |= 1 << r; // produces 8
If you tried to invert it, you wouldn't be able to tell whether the original value is 0 or 8.
A similar situation applies to the & AND operator.
From an information-theory perspective:
The operators | and & incur a loss of information and do not preserve the entropy of the data.
On the other hand, operators such as ^ (XOR), +, and - are one-to-one and thus preserve entropy and are invertible.
No, OR is not reversable. I believe only XOR is.
For example, if variable a contains 1001 1100 or 1001 1000, and you set the third bit (from the right) to 1 regardless of what the initial value is, then both 1001 1100 and 1001 1000 as source operands would result in the same value (1001 1100).
Firstly, 1<<2 is just another way of writing "4" or 100 in binary.
The |= operator is another way of writing x = x | y;
The end result is setting bit 2 in x. If bit 2 in x was zero then reversing it would be to clear bit 2. If bit 2 was 1, then it's a no-op.
The problem with your question is that you don't know ahead of time what the initial state of bit 2 was.
If your goal was to clear bit 2 you can do this:
x &= ~(1<<2);
Given an expression result |= 1 << shiftAmount, corresponding to VAR and r in your original example, you can use the following to do the exact opposite:
result &= ~(1 << shiftAmount)
Note that this is not a pure inverse, because bitwise-or is not a one-to-one function. Bitwise-or sets one or more bits to 1, whether or not they were already 0 or 1. The expression I have shown above will always set the associated bits to 0, so if the bit was 1 originally it will not go back to its original state.
No, you can't reverse an OR operation.
In your example, with r=3, both the starting values VAR=192 and VAR=200 will result in 200.
Since there are two input values that will give the same result, you won't know which one to go back to.
I am learning C/C++ programming & have encountered the usage of 'Bit arrays' or 'Bit Vectors'. Am not able to understand their purpose? here are my doubts -
Are they used as boolean flags?
Can one use int arrays instead? (more memory of course, but..)
What's this concept of Bit-Masking?
If bit-masking is simple bit operations to get an appropriate flag, how do one program for them? is it not difficult to do this operation in head to see what the flag would be, as apposed to decimal numbers?
I am looking for applications, so that I can understand better. for Eg -
Q. You are given a file containing integers in the range (1 to 1 million). There are some duplicates and hence some numbers are missing. Find the fastest way of finding missing
numbers?
For the above question, I have read solutions telling me to use bit arrays. How would one store each integer in a bit?
I think you've got yourself confused between arrays and numbers, specifically what it means to manipulate binary numbers.
I'll go about this by example. Say you have a number of error messages and you want to return them in a return value from a function. Now, you might label your errors 1,2,3,4... which makes sense to your mind, but then how do you, given just one number, work out which errors have occured?
Now, try labelling the errors 1,2,4,8,16... increasing powers of two, basically. Why does this work? Well, when you work base 2 you are manipulating a number like 00000000 where each digit corresponds to a power of 2 multiplied by its position from the right. So let's say errors 1, 4 and 8 occur. Well, then that could be represented as 00001101. In reverse, the first digit = 1*2^0, the third digit 1*2^2 and the fourth digit 1*2^3. Adding them all up gives you 13.
Now, we are able to test if such an error has occured by applying a bitmask. By example, if you wanted to work out if error 8 has occured, use the bit representation of 8 = 00001000. Now, in order to extract whether or not that error has occured, use a binary and like so:
00001101
& 00001000
= 00001000
I'm sure you know how an and works or can deduce it from the above - working digit-wise, if any two digits are both 1, the result is 1, else it is 0.
Now, in C:
int func(...)
{
int retval = 0;
if ( sometestthatmeans an error )
{
retval += 1;
}
if ( sometestthatmeans an error )
{
retval += 2;
}
return retval
}
int anotherfunc(...)
{
uint8_t x = func(...)
/* binary and with 8 and shift 3 plaes to the right
* so that the resultant expression is either 1 or 0 */
if ( ( ( x & 0x08 ) >> 3 ) == 1 )
{
/* that error occurred */
}
}
Now, to practicalities. When memory was sparse and protocols didn't have the luxury of verbose xml etc, it was common to delimit a field as being so many bits wide. In that field, you assign various bits (flags, powers of 2) to a certain meaning and apply binary operations to deduce if they are set, then operate on these.
I should also add that binary operations are close in idea to the underlying electronics of a computer. Imagine if the bit fields corresponded to the output of various circuits (carrying current or not). By using enough combinations of said circuits, you make... a computer.
regarding the usage the bits array :
if you know there are "only" 1 million numbers - you use an array of 1 million bits. in the beginning all bits will be zero and every time you read a number - use this number as index and change the bit in this index to be one (if it's not one already).
after reading all numbers - the missing numbers are the indices of the zeros in the array.
for example, if we had only numbers between 0 - 4 the array would look like this in the beginning: 0 0 0 0 0.
if we read the numbers : 3, 2, 2
the array would look like this: read 3 --> 0 0 0 1 0. read 3 (again) --> 0 0 0 1 0. read 2 --> 0 0 1 1 0. check the indices of the zeroes: 0,1,4 - those are the missing numbers
BTW, of course you can use integers instead of bits but it may take (depends on the system) 32 times memory
Sivan
Bit Arrays or Bit Vectors can be though as an array of boolean values. Normally a boolean variable needs at least one byte storage, but in a bit array/vector only one bit is needed.
This gets handy if you have lots of such data so you save memory at large.
Another usage is if you have numbers which do not exactly fit in standard variables which are 8,16,32 or 64 bit in size. You could this way store into a bit vector of 16 bit a number which consists of 4 bit, one that is 2 bit and one that is 10 bits in size. Normally you would have to use 3 variables with sizes of 8,8 and 16 bit, so you only have 50% of storage wasted.
But all these uses are very rarely used in business aplications, the come to use often when interfacing drivers through pinvoke/interop functions and doing low level programming.
Bit Arrays of Bit Vectors are used as a mapping from position to some bit value. Yes it's basically the same thing as an array of Bool, but typical Bool implementation is one to four bytes long and it uses too much space.
We can store the same amount of data much more efficiently by using arrays of words and binary masking operations and shifts to store and retrieve them (less overall memory used, less accesses to memory, less cache miss, less memory page swap). The code to access individual bits is still quite straightforward.
There is also some bit field support builtin in C language (you write things like int i:1; to say "only consume one bit") , but it is not available for arrays and you have less control of the overall result (details of implementation depends on compiler and alignment issues).
Below is a possible way to answer to your "search missing numbers" question. I fixed int size to 32 bits to keep things simple, but it could be written using sizeof(int) to make it portable. And (depending on the compiler and target processor) the code could only be made faster using >> 5 instead of / 32 and & 31 instead of % 32, but that is just to give the idea.
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
int main(){
/* put all numbers from 1 to 1000000 in a file, except 765 and 777777 */
{
printf("writing test file\n");
int x = 0;
FILE * f = fopen("testfile.txt", "w");
for (x=0; x < 1000000; ++x){
if (x == 765 || x == 777760 || x == 777791){
continue;
}
fprintf(f, "%d\n", x);
}
fprintf(f, "%d\n", 57768); /* this one is a duplicate */
fclose(f);
}
uint32_t bitarray[1000000 / 32];
/* read file containing integers in the range [1,1000000] */
/* any non number is considered as separator */
/* the goal is to find missing numbers */
printf("Reading test file\n");
{
unsigned int x = 0;
FILE * f = fopen("testfile.txt", "r");
while (1 == fscanf(f, " %u",&x)){
bitarray[x / 32] |= 1 << (x % 32);
}
fclose(f);
}
/* find missing number in bitarray */
{
int x = 0;
for (x=0; x < (1000000 / 32) ; ++x){
int n = bitarray[x];
if (n != (uint32_t)-1){
printf("Missing number(s) between %d and %d [%x]\n",
x * 32, (x+1) * 32, bitarray[x]);
int b;
for (b = 0 ; b < 32 ; ++b){
if (0 == (n & (1 << b))){
printf("missing number is %d\n", x*32+b);
}
}
}
}
}
}
That is used for bit flags storage, as well as for parsing different binary protocols fields, where 1 byte is divided into a number of bit-fields. This is widely used, in protocols like TCP/IP, up to ASN.1 encodings, OpenPGP packets, and so on.