C++ bitfield testing - c++

Is there a more compact way of comparing my bits than this (the only way I know):
#define BIT1 1
#define BIT2 2
#define BIT3 4
#define BIT4 8
#define BIT5 16
#define BIT6 32
// I declare this somewhere in a structure
unsigned char bits: 6;
// I want all of them to be 0 at first (000000)
bits = 0;
/* I do some bite setting here */
// I only want to know if the state of my bits == 000000
if(bits & (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6) == (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6))
{
// All kinds of nasty stuff
}
I thought maybe something in the lines of bits & 0x00 == 0x00

If you want compact (as indicated in your comment) rather than fast, why not do something like:
#define BIT1 0x01
#define BIT2 0x02
#define BIT3 0x04
#define BIT4 0x08
#define BIT5 0x10
#define BIT6 0x20
#define BITS1THRU4 (BIT1|BIT2|BIT3|BIT4)
// or #define BITS1THRU6 0x0f
// I declare this somewhere in a structure
unsigned char bits: 6;
// I want all of them to be 0 at first (000000)
bits = 0;
/* I do some bit setting here */
// I only want to know if the state of my first four bits == 0000
if(bits & BITS1THRU4 == 0) ...
It probably won't be any faster since your original code would have been turned into that constant anyway but it may be more readable (which is often a good reason to do it).
If you have a need for other variations, just define them. If there's too many of them (63 defines, if you use them all, may be getting a bit on the high side), I'd start thinking about another solution.
But, to be honest, unless you're going to use more meaningful names for the defines, I'd just ditch them. The name BIT3 really adds nothing to 0x04 to those that understand bit patterns. If it was something like UART_READ_READY_BIT, that would be fine but what you have is only slightly better than:
#define THREE 3
(no offence intended, I'm just pointing out my views). I'd just work out the bit patterns and put them straight in the code (bits 1 thru 6 in your case being 0x3f).
And, just as an aside, for you particular case, I think bits will only be those six bits anyway so you may find it's enough to compare it to 0 (with no bit masking). I've left in the bit masking method in case you wanted a mode general solution for checking specific bits.

if( ~bits & (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6) == (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6))
And about speed (BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6) is actualy compiled as constant and there are only few operation (like 2) for this if - one NOR and one compare (i am not sure if x386 supprts NOR, but i think it does)

if I read your condition right (with corrected parentheses, as per #user547710), you check if all your bits are set, rather than zero.
Anyway, you can define a mask with bits 1-6 set more compactly by (1u << 6) - 1. This is compile-time constant expression, so you need not to worry about extra computing time. I'd do:
const unsigned char bitmask6 = 1u << 6) - 1;
if ((bits & bitmask6) == bitmask6)

Though this is just a note,
operator == has higher precedence than &,
the logical-and should be parenthesized as:
if((a & b) == c)
I interpreted that this is the intention of the questioner.
(I think this should be posted as just a comment,
but it seems that I can't post a comment)

Related

assigning two 8 bit bitsets to one 16 bit bitset

Is there any way I can assign two 8 bit bitsets to one 16 bit bitset
e.g.
bitset<8> first = var1;
bitset<8> second = var2;
bitset<16> = first+second;
if you want them to be serialized:
bitset<16> result(first.to_ulong() * 0x100 + second.to_ulong());
this makes first to the most significant and second to least significant bits.
Shift the first bits size over.
This is assuming that first.size() + second.size() is not any bigger than ullong in c++11.
bitset<first.size()+second.size()> third(first.to_ullong() << first.size() | second.to_ullong());
If you're not constrained to use bitset<>, you might find that the bit-wise operators are most suitable for such manipulations. Certainly, it's much more terse, which may or may not be suitable or to your liking. E.g.,
unsigned bit_1 = 0xff, // low order 8 bits set
bit_2 = 0xff00, // high order 8 bits set
bit_3 = 0,
bit_4 = 0x1ce9;
bit_3 = bit_1 | bit_2; // now bit_3 has all 16 bits set
bit_3 ^= bit_3; // every bit that was set is now cleared
bit_3 = bit_4 & bit_1; // using bit_1 as a mask, bit_3 now contains just the
// lower order bits that are set in bit_4, 0xe9

Declare a bit in C++

I write a program with highly memory cost requirement and I want save memory with no performance lost.
So I want change every variable which has only two situations into bit.
But I can't find bit type in C++ and bitset in STL is always multiples of 4 byte in 32-bit machine.
Writing a data struct to manage bits will cause performance lost.
Is there any way to declare a bit value just like bit a;?
Thanks everyone. At last the answer I want is:"you can't buy half bytes in C++".
There is none. The smallest addressable entity is a byte. This is the char or unsigned char type. (The best type is the integer because it is aligned to the width of your processor and thus fastest to fetch and work on)
To work with bits you need to use boolean operators and mask/shift your data in the larger types. Or work with STL bitsets.
source: http://www.learncpp.com/cpp-tutorial/3-8a-bit-flags-and-bit-masks/
If you are using simple booleans, the above example displays how you can adress them to seperate bit values inside of bytes.
C++14
Define 8 separate bit flags (these can represent whatever you want)
const unsigned char option1 = 0b0000'0001;
const unsigned char option2 = 0b0000'0010;
const unsigned char option3 = 0b0000'0100;
const unsigned char option4 = 0b0000'1000;
const unsigned char option5 = 0b0001'0000;
const unsigned char option6 = 0b0010'0000;
const unsigned char option7 = 0b0100'0000;
const unsigned char option8 = 0b1000'0000;
C++11 or earlier
Define 8 separate bit flags (these can represent whatever you want)
const unsigned char option1 = 0x1; // hex for 0000 0001
const unsigned char option2 = 0x2; // hex for 0000 0010
const unsigned char option3 = 0x4; // hex for 0000 0100
const unsigned char option4 = 0x8; // 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
We use a byte-size value to hold our options
Each bit in myflags corresponds to one of the options defined above
unsigned char myflags = 0; -- all options turned off to start
To query a bit state, we use bitwise AND ('&' operator):
if (myflags & option4) ... -- if option4 is set, do something
if !(myflags & option5) ... -- if option5 is not set, do something
To set a bit (turn on), we use bitwise OR('|' operator):
myflags |= option4; -- turn option 4 on.
myflags |= (option4 | option5); -- turn options 4 and 5 on.
To clear a bit (turn off), we use bitwise AND with an inverse(~) bit pattern:
myflags &= ~option4; -- turn option 4 off
myflags &= ~(option4 | option5); -- turn options 4 and 5 off
To toggle a bit state, we use bitwise XOR:
myflags ^= option4; -- flip option4 from on to off, or vice versa
myflags ^= (option4 | option5); -- flip options 4 and 5
You can use: static_cast(value) to turn said value into a bool.
There is no such data type as a "bit" specifically. The a practice is to use a standard uint8_t (or uint16, 32) and use the individual bits for different values. E.g.:
#define BIT1 0x01
#define BIT2 0x02
#define BIT3 0x04
#define BIT4 0x08
uint8_t bit_vars;
// Make a function to access a particular bit
uint8_t get_bitx(int x)
{
switch (x)
{
case 1:
return bit_vars & BIT1;
break;
case 2:
return bit_vars & BIT2;
break;
case 3:
return bit_vars & BIT3;
break;
case 4:
return bit_vars & BIT4;
break;
}
// Make a function to set/storea particular bit
void set_bitx(int x, bool set_flag)
{
switch (x)
{
case 1:
if (set_flag) {bit_vars |= 1 << (BIT1 - 1);}
break;
case 2:
if (set_flag) {bit_vars |= 1 << (BIT2 - 1);}
break;
case 3:
if (set_flag) {bit_vars |= 1 << (BIT3 - 1);}
break;
case 4:
if (set_flag) {bit_vars |= 1 << (BIT4 - 1);}
break;
}
Note: This is just a rough example, not compilable.
You can also use bit-fields, I personally tend to stay away from them, as they are not always portable across different processors / compilers.
You can use bit fields. Or use std::vector with bool type, which has template specialization.
use an integer storage (32 bits) where bit represent 1 variable.
indeed this makes your code ugly but if you wish to have memory optimization, you have to pay somewhere else.
Accessing each variable's "bit" should be done by bit-wise operations on that integer.

How can I use a bitmask?

How do I use it in C++? When is it useful to use?
What would be an example of a problem where a bitmask is used to see how it actually works?
Briefly, a bitmask helps to manipulate the 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
// it should generally only use the = operator when initialising variables.
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++ Tricks.
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);
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.
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.

Bit shifts and their logical operators

This program below moves the last (junior) and the penultimate bytes variable i type int. I'm trying to understand why the programmer wrote this
i = (i & LEADING_TWO_BYTES_MASK) | ((i & PENULTIMATE_BYTE_MASK) >> 8) | ((i & LAST_BYTE_MASK) << 8);
Can anyone explain to me in plain English whats going on in the program below.
#include <stdio.h>
#include <cstdlib>
#define LAST_BYTE_MASK 255 //11111111
#define PENULTIMATE_BYTE_MASK 65280 //1111111100000000
#define LEADING_TWO_BYTES_MASK 4294901760 //11111111111111110000000000000000
int main(){
unsigned int i = 0;
printf("i = ");
scanf("%d", &i);
i = (i & LEADING_TWO_BYTES_MASK) | ((i & PENULTIMATE_BYTE_MASK) >> 8) | ((i & LAST_BYTE_MASK) << 8);
printf("i = %d", i);
system("pause");
}
Since you asked for plain english: He swaps the first and second bytes of an integer.
The expression is indeed a bit convoluted but in essence the author does this:
// Mask out relevant bytes
unsigned higher_order_bytes = i & LEADING_TWO_BYTES_MASK;
unsigned first_byte = i & LAST_BYTE_MASK;
unsigned second_byte = i & PENULTIMATE_BYTE_MASK;
// Switch positions:
unsigned first_to_second = first_byte << 8;
unsigned second_to_first = second_byte >> 8;
// Concatenate back together:
unsigned result = higher_order_bytes | first_to_second | second_to_first;
Incidentally, defining the masks using hexadecimal notation is more readable than using decimal. Furthermore, using #define here is misguided. Both C and C++ have const:
unsigned const LEADING_TWO_BYTES_MASK = 0xFFFF0000;
unsigned const PENULTIMATE_BYTE_MASK = 0xFF00;
unsigned const LAST_BYTE_MASK = 0xFF;
To understand this code you need to know what &, | and bit shifts are doing on the bit level.
It's more instructive to define your masks in hexadecimal rather than decimal, because then they correspond directly to the binary representations and it's easy to see which bits are on and off:
#define LAST 0xFF // all bits in the first byte are 1
#define PEN 0xFF00 // all bits in the second byte are 1
#define LEAD 0xFFFF0000 // all bits in the third and fourth bytes are 1
Then
i = (i & LEAD) // leave the first 2 bytes of the 32-bit integer the same
| ((i & PEN) >> 8) // take the 3rd byte and shift it 8 bits right
| ((i & LAST) << 8) // take the 4th byte and shift it 8 bits left
);
So the expression is swapping the two least significant bytes while leaving the two most significant bytes the same.

How masking works

I am new at C, and I am debugging with source code. However, I am confused with this code snippet.
When the values are assigned to the structure value, I think it is some masking. But not sure, and if it is masking. How does masking work in this concept?
Many thanks,
#define MSGINFO_ENABLE 0x01
#define MIME_ENABLE 0x02
#define FASTSTART_CODERS_IN_OFFERED 0x04
#define TRANSADDR_ENABLE 0x08
typedef struct {
unsigned int msginfo_mask; /* added in version 0x0101 */
} VIRTBOARD;
VIRTBOARD VirtBoard;
/* Not sure I understand what is happening here. */
VirtBoard.msginfo_mask = MSGINFO_ENABLE | MIME_ENABLE | FASTSTART_CODERS_IN_OFFERED | TRANSADDR_ENABLE;
Ok in plain English:
The Hexdecimal numbers 0x01,0x02,0x04,0x08 were each selected BECAUSE they are each encoded as different single bits being set in binary. None of the bit maps overlap so each one can be read and set without being effected by the other bits. Adding the following comments to your code makes it clearer what's happening:
#define MSGINFO_ENABLE 0x01 // => 0001
#define MIME_ENABLE 0x02 // => 0010
#define FASTSTART_CODERS_IN_OFFERED 0x04 // => 0100
#define TRANSADDR_ENABLE 0x08 // => 1000
Now adding a comment before the other line shows the result:
// VirtBoard.msginfo_mask |= 0001
// VirtBoard.msginfo_mask |= 0010
// VirtBoard.msginfo_mask |= 0100
// VirtBoard.msginfo_mask |= 1000
// ----
// VirtBoard.msginfo_mask == 1111
VirtBoard.msginfo_mask = MSGINFO_ENABLE |
MIME_ENABLE |
FASTSTART_CODERS_IN_OFFERED |
TRANSADDR_ENABLE;
While the comments on the assignment make it clear what's going on, once you understand what's happening, the comments kinda defeat the purpose of symbolically defining constants.
It might help to think of it this way (values shown in binary):
MSGINFO_ENABLE = 0001
MIME_ENABLE = 0010
FASTSTART_CODERS_IN_OFFERED = 0100
TRANSADDR_ENABLE = 1000
So...
1001 is TRANSADDR_ENABLE and MSGINFO_ENABLE
or
1101 is eveything but FASTSTART_CODERS_IN_OFFERED
Does that help at all? The | notation is C syntax to set the correct bit:
int something = 0;
something = MSGINFO_ENABLE | TRANSADDR_ENABLE;
is the a syntax to set only those 2 bits.
Your variable, msginfo_mask, when represented as a binary number (1's and 0's) is used as a "mask" by setting certain bits to 1 (using bit-wise OR) or clearing certain bits to 0 (using bit-wise AND). Your code snippet sets certain bits to 1 while leaving others unchanged. Masking is comparable to how a painter masks off areas that they do not want to be painted.
If you look at the #defines at the top of your code, you will notice that each number represents a single bit when written out in binary:
#define MSGINFO_ENABLE 0x01 <-- 0001 in binary
#define MIME_ENABLE 0x02 <-- 0010 in binary
#define FASTSTART_CODERS_IN_OFFERED 0x04 <-- 0100 in binary
#define TRANSADDR_ENABLE 0x08 <-- 1000 in binary
Setting bits is done by using the OR function. If you OR a bit with 1, the result is always going to be a 1. If you OR a bit with 0, the original value will not be changed.
So, when you see:
msginfo_mask = MSGINFO_ENABLE | MIME_ENABLE |
FASTSTART_CODERS_IN_OFFERED | TRANSADDR_ENABLE;
What you are saying is "take the value of msginfo_mask and OR it with (binary) 0001, 0010, 0100, and 1000. This is the same thing as saying "set bit 0, bit 1, bit 2, and bit 3."
The binary operator '|' is the bitwise-or operator; for each bit in the two input words, if either bit is a 1, then the corresponding bit in the result is a 1:
0001 | 0010 = 0011
The '|' operator is typically used to set individual bits in a word, such as in the code snippet you posted.
The binary operator '&' is the bitwise-and operator; for each bit in the two input words, if both bits are 1, then the corresponding bit in the result is a 1:
0101 & 0110 = 0100
The '&' operator can be used to test if a bit is set. For example, to test if the MSGINFO_ENABLE bit is set, you'd do something like
if (VirtBoard.msginfo_mask & MSGINFO_ENABLE != 0)
{
/* MSGINFO_ENABLE bit is set, do something interesting */
}
The expression
VirtBoard.msginfo_mask & MSGINFO_ENABLE
will evaluate to 1 (0x0001) if the MSGINFO_ENABLE bit was set,0 otherwise.
The unary operator '~' is the bitwise-not operator; for each bit in the input word, the corresponding bit in the result is set to the opposite value:
~ 0001 = 1110
You can use the '~' operator together with the '&' operator to clear an individual bit. For example, if we wanted to clear the MSGINFO_ENABLE bit, we'd do something like
VirtBoard.msginfo_mask = VirtBoard.msginfo_mask & ~MSGINFO_ENABLE;
which can be shortened to
VirtBoard.msginfo_mask &= ~MSGINFO_ENABLE;
Negating MSGINFO_ ENABLE gives us 1111111111111110 (assuming a 16-bit unsigned int); since the leading bits are all 1, and-ing this against the VirtBoard.msginfo_ mask preserves any bits that are already set; i.e., 0000000000001111 & 1111111111111110 = 0000000000001110.
If we wanted to clear both the MSGINFO _ENABLE and TRANSADDR _ENABLE bits, we'd combine all the operators like so:
VirtBoard.msginfo_mask &= ~(MSGINFO_ENABLE | TRANSADDER_ENABLE)
The programmer is setting the mask to a certain bit value. In this case:
VitBoard.msginfo_mask = 0x01 | 0x02 | 0x04 = 0x07
Assuming the code handles messages, when a message comes in they may compare it to this mask to see what is enabled in the message.
if((newMsg & VitBoard.msginfo_mask) == 0x07)
{
//do something related to mime enable, msginfo enable and faststart
}
Notice the "&" operator to do the mask comparisons.
The other part is that "or" the masks together are probably being used as switches to enable/disable certain functionality. In the examples you have written, it looks like possibly output at different levels or parts of the codes.
The defined masks can be used to check the functionality to see if it is enable or disabled. For example:
VirtBoard.msginfo_mask = MSGINFO_ENABLE | MIME_ENABLE ;
if ( VirtBoard.msginfo_mask & MSGINFO_ENABLE )
{
printf("Messages enabled\n";
}
if ( VirtBoard.msginfo_mask & TRANSADDR_ENABLE)
{
printf("Transaddress enabled\n");
}
In the first if, since MSGINFO_ENABLED mask was "or" and assigned to the variable, when you apply an "and" operation with the variable and MSGINOF_ENABLED mask, a non zero value is returned, indicating it is true. So the printf statement will be executed.
In the case of the second if, since TRANSADDR_ENABLE was not "or" in to the variable, when an "and" is used with the variable and TRANSADDR_ENABLE mask, it will return a zero value, so no message will be printed.