Retrieve specific bit from a bit mask [duplicate] - c

I don't quite understand this whole bitmask concept.
Let's say I have a mask:
var bitMask = 8 | 524288;
I undestand that this is how I would combine 8 and 524288, and get 524296.
BUT, how do I go the other way? How do I check my bitmask, to see if it contains 8 and/or 524288?
To make it a bit more complex, let's say the bitmask I have is 18358536 and I need to check if 8 and 524288 are in that bitmask. How on earth would I do that?

well
if (8 & bitmask == 8 ) {
}
will check if the bitmask contains 8.
more complex
int mask = 8 | 12345;
if (mask & bitmask == mask) {
//true if, and only if, bitmask contains 8 | 12345
}
if (mask & bitmask != 0) {
//true if bitmask contains 8 or 12345 or (8 | 12345)
}
may be interested by enum and more particularly FlagsAttibute.

I'm pretty sure (A & B)==B where A is the bitmask and B is whatever you want to check should do.
Example:
if((18358536 & 8) == 8)
{
// mask contains 8
}

First of all, bitmasks are for operating on bits, not integers. It is much easier to understand when we deal with just 1's and 0's than more complex numbers.
So for example:
1000110000010000100001000 = 18358536 // in binary.
0000010000000000000000000 = 524288 // in binary.
0000000000000000000001000 = 8 // in binary.
0000010000000000000001000 = 524296 // in binary.
With this, it is clear that integer 8 is a 4th bit from the right side and no other bits marked, so when we add 8 to 524288 (20th bit only) we are simply marking 4th and 20th bits as being true. So we can use the same space in memory reserved for an integer to hold multiple flags that define some boolean properties.
As Alex already explained, you can then check if any flag is available in bitmask by using bitwise AND operator:
if ((mask & flag) == flag) { /* mask has flag set as true */ }
You can read everything about bitmasks in this article

Related

Bitshifting and making sure the last two digits are 10 in C

How do I bitshift so I only need to compare the first two digits in a number? Say I want to compare 10101011010 the last two bits and make sure it's 10.
How would I do that?
If you want to check if certain bits are set in an integer, you'd use the binary and operator (&) and a mask. In the mask you set the bits you want to check and then use this mask to separate the bits you want to check.
So in your example:
val = b10101011010
And you want to make sure the last 2 bits are 10:
y = b10 = 0x02 = 2
than you make the mask so it selects the last 2 bits:
mask = b00000000011 = 0x03 = 3 (I'd use the hex notation to make it more clear)
or you could use bitshifting:
mask = (0x01 << 0) | (0x01 << 1) (setting bit 0 and bit 1 and oring them together)
Now we use the binary and operator:
val = b10101011010
mask = b00000000011
& -----------------
res = b00000000010
--> now we have our bits we are interested in
and we compare res with the value you want them to be:
if (res == y)
// -> good
else
// -> bad

Changing more than one bit in a register

I have an 8 bit register and I want to change bits 4,5 and 6 without altering the other bits.
Those bit can take values from 000 to 111 (regardless their previous state).
Is there a method to change them in one step or must I change them individually?
You need a mask to put the requested bits in a known state, 0 is the more convenient as per my programming habits, then set the bits that you want to 1 with an or operation and write back:
#define mask 0x70 // 01110000b bit 4, 5 & 6 set
reg = (reg & ~mask) | (newVal & mask);
We use the inverted mask to set to 0 the bits to change and the unchanged mask to set to 0 the bits that we don't want to interfere from the new value.
If you are sure that the unwanted bits of the new value are always 0 you can simplify:
#define mask 0x8f // 10001111b bit 4, 5 & 6 reset
reg = (reg & mask) | newVal; //newVal must have always bits 7, 3, 2, 1 & 0 reset.
You can do it by bitwise operation, i.e. first clear the 3 bits, and then set them:
unsigned char value = 0x70;
unsigned char r = 0xFF;
r = (r & 0x8F) | value;
You can use bit-field inside a struct:
typedef struct{
unsigned char b0_3 : 4;
unsigned char b4_6 : 3;
unsigned char b7 : 1;
}your_reg_type;
your_reg_type my_register;
//modify only the bits you need
my_register.b4_6 = 0x02;
Check out how your compiler orders the bits inside the struct before trying and order your bit-field accordingly
A number of solutions and variations are possible (and have been suggested already), but if the value of the three consecutive bits has meaning in-itself (i.e. it is a value 0 to 7 rather then simply a collection of independent flag or control bits for example), it may be useful to keep the value as a simple numeric range 0 to 7 rather then directly encoding details of bit position within the value. In which case:
assert( val <= 7 ) ; // During debug (when NDEBUG not defined) the
// assert trap will catch out-of-range inputs
reg = (reg & mask) | (val << 4) ;
Of course there is some small cost to pay for simplifying the interface in this way (by adding a shift operation), but the advantage is that knowledge of the details of the register field layout is restricted to one place.

How do you compare only certain bits in data type?

I'm trying to learn a bit about emulation and I'm trying to think of how I can decode opcodes. Each opcode is a short data type, 16 bits. I'd like to be able to compare only specific sets of 4 bits. For example: there are multiple opcodes that start with 00, such as 0x00E0.
I'd like to be able to compare each of these values in either bit or hexidecimal form. I was thinking maybe something along the lines of bit shifting to bump of everything else off so that the bits I don't care about would zero out. That may cause issues for the center bits and will require additional steps. What kind of solutions do you guys use for a problem like this?
Use a bit mask, which has the bits set that you care about. Then use the & operator to zero out everything that you don't care about. For instance, say we want to compare the lowest four bits in a and b:
uint16 mask = 0x000f;
if ((a & mask) == (b & mask)) {
// lowest 4 bits are equal
}
This is simple bit manipulation. You can mask the relevant bits with
int x = opcode & 0x00f0;
and compare the resulting value
if (x == 0x00e0) {
/* do something */
}
you can easily create the mask of "nbits" and and shift "pos" number of bits and do comparision
uint32_t mask = ~((~0) << nbits);
if( (num(mask << pos)) == 0x00e0 ) {
/* Do something */
}

Explain this Function

Can someone explain to me the reason why someone would want use bitwise comparison?
example:
int f(int x) {
return x & (x-1);
}
int main(){
printf("F(10) = %d", f(10));
}
This is what I really want to know: "Why check for common set bits"
x is any positive number.
Bitwise operations are used for three reasons:
You can use the least possible space to store information
You can compare/modify an entire register (e.g. 32, 64, or 128 bits depending on your processor) in a single CPU instruction, usually taking a single clock cycle. That means you can do a lot of work (of certain types) blindingly fast compared to regular arithmetic.
It's cool, fun and interesting. Programmers like these things, and they can often be the differentiator when there is no difference between techniques in terms of efficiency/performance.
You can use this for all kinds of very handy things. For example, in my database I can store a lot of true/false information about my customers in a tiny space (a single byte can store 8 different true/false facts) and then use '&' operations to query their status:
Is my customer Male and Single and a Smoker?
if (customerFlags & (maleFlag | singleFlag | smokerFlag) ==
(maleFlag | singleFlag | smokerFlag))
Is my customer (any combination of) Male Or Single Or a Smoker?
if (customerFlags & (maleFlag | singleFlag | smokerFlag) != 0)
Is my customer not Male and not Single and not a Smoker)?
if (customerFlags & (maleFlag | singleFlag | smokerFlag) == 0)
Aside from just "checking for common bits", you can also do:
Certain arithmetic, e.g. value & 15 is a much faster equivalent of value % 16. This only works for certain numbers, but if you can use it, it can be a great optimisation.
Data packing/unpacking. e.g. a colour is often expressed as a 32-bit integer that contains Alpha, Red, Green and Blue byte values. The Red value might be extracted with an expression like red = (value >> 16) & 255; (shift the value down 16 bit positions and then carve off the bottom byte)
Data manipulation and swizzling. Some clever tricks can be achieved with bitwise operations. For example, swapping two integer values without needing to use a third temporary variable, or converting ARGB colour values into another format (e.g RGBA or BGRA)
The Ur-example is "testing if a number is even or odd":
unsigned int number = ...;
bool isOdd = (0 != (number & 1));
More complex uses include bitmasks (multiple boolean values in a single integer, each one taking up one bit of space) and encryption/hashing (which frequently involve bit shifting, XOR, etc.)
The example you've given is kinda odd, but I'll use bitwise comparisons all the time in embedded code.
I'll often have code that looks like the following:
volatile uint32_t *flags = 0x000A000;
bool flagA = *flags & 0x1;
bool flagB = *flags & 0x2;
bool flagC = *flags & 0x4;
It's not a bitwise comparison. It doesn't return a boolean.
Bitwise operators are used to read and modify individual bits of a number.
n & 0x8 // Peek at bit3
n |= 0x8 // Set bit3
n &= ~0x8 // Clear bit3
n ^= 0x8 // Toggle bit3
Bits are used in order to save space. 8 chars takes a lot more memory than 8 bits in a char.
The following example gets the range of an IP subnet using given an IP address of the subnet and the subnet mask of the subnet.
uint32_t mask = (((255 << 8) | 255) << 8) | 255) << 8) | 255;
uint32_t ip = (((192 << 8) | 168) << 8) | 3) << 8) | 4;
uint32_t first = ip & mask;
uint32_t last = ip | ~mask;
e.g. if you have a number of status flags in order to save space you may want to put each flag as a bit.
so x, if declared as a byte, would have 8 flags.
I think you mean bitwise combination (in your case a bitwise AND operation). This is a very common operation in those cases where the byte, word or dword value is handled as a collection of bits, eg status information, eg in SCADA or control programs.
Your example tests whether x has at most 1 bit set. f returns 0 if x is a power of 2 and non-zero if it is not.
Your particular example tests if two consecutive bits in the binary representation are 1.

bitwise indexing in C?

I'm trying to implement a data compression idea I've had, and since I'm imagining running it against a large corpus of test data, I had thought to code it in C (I mostly have experience in scripting languages like Ruby and Tcl.)
Looking through the O'Reilly 'cow' books on C, I realize that I can't simply index the bits of a simple 'char' or 'int' type variable as I'd like to to do bitwise comparisons and operators.
Am I correct in this perception? Is it reasonable for me to use an enumerated type for representing a bit (and make an array of these, and writing functions to convert to and from char)? If so, is such a type and functions defined in a standard library already somewhere? Are there other (better?) approaches? Is there some example code somewhere that someone could point me to?
Thanks -
Following on from what Kyle has said, you can use a macro to do the hard work for you.
It is possible.
To set the nth bit, use OR:
x |= (1 << 5); // sets the 6th-from
right
To clear a bit, use AND:
x &= ~(1 << 5); // clears
6th-from-right
To flip a bit, use XOR:
x ^= (1 << 5); // flips 6th-from-right
Or...
#define GetBit(var, bit) ((var & (1 << bit)) != 0) // Returns true / false if bit is set
#define SetBit(var, bit) (var |= (1 << bit))
#define FlipBit(var, bit) (var ^= (1 << bit))
Then you can use it in code like:
int myVar = 0;
SetBit(myVar, 5);
if (GetBit(myVar, 5))
{
// Do something
}
It is possible.
To set the nth bit, use OR:
x |= (1 << 5); // sets the 5th-from right
To clear a bit, use AND:
x &= ~(1 << 5); // clears 5th-from-right
To flip a bit, use XOR:
x ^= (1 << 5); // flips 5th-from-right
To get the value of a bit use shift and AND:
(x & (1 << 5)) >> 5 // gets the value (0 or 1) of the 5th-from-right
note: the shift right 5 is to ensure the value is either 0 or 1. If you're just interested in 0/not 0, you can get by without the shift.
Have a look at the answers to this question.
Theory
There is no C syntax for accessing or setting the n-th bit of a built-in datatype (e.g. a 'char'). However, you can access bits using a logical AND operation, and set bits using a logical OR operation.
As an example, say that you have a variable that holds 1101 and you want to check the 2nd bit from the left. Simply perform a logical AND with 0100:
1101
0100
---- AND
0100
If the result is non-zero, then the 2nd bit must have been set; otherwise is was not set.
If you want to set the 3rd bit from the left, then perform a logical OR with 0010:
1101
0010
---- OR
1111
You can use the C operators && (for AND) and || (for OR) to perform these tasks. You will need to construct the bit access patterns (the 0100 and 0010 in the above examples) yourself. The trick is to remember that the least significant bit (LSB) counts 1s, the next LSB counts 2s, then 4s etc. So, the bit access pattern for the n-th LSB (starting at 0) is simply the value of 2^n. The easiest way to compute this in C is to shift the binary value 0001 (in this four bit example) to the left by the required number of places. As this value is always equal to 1 in unsigned integer-like quantities, this is just '1 << n'
Example
unsigned char myVal = 0x65; /* in hex; this is 01100101 in binary. */
/* Q: is the 3-rd least significant bit set (again, the LSB is the 0th bit)? */
unsigned char pattern = 1;
pattern <<= 3; /* Shift pattern left by three places.*/
if(myVal && (char)(1<<3)) {printf("Yes!\n");} /* Perform the test. */
/* Set the most significant bit. */
myVal |= (char)(1<<7);
This example hasn't been tested, but should serve to illustrate the general idea.
To query state of bit with specific index:
int index_state = variable & ( 1 << bit_index );
To set bit:
varabile |= 1 << bit_index;
To restart bit:
variable &= ~( 1 << bit_index );
Try using bitfields. Be careful the implementation can vary by compiler.
http://publications.gbdirect.co.uk/c_book/chapter6/bitfields.html
IF you want to index a bit you could:
bit = (char & 0xF0) >> 7;
gets the msb of a char. You could even leave out the right shift and do a test on 0.
bit = char & 0xF0;
if the bit is set the result will be > 0;
obviousuly, you need to change the mask to get different bits (NB: the 0xF is the bit mask if it is unclear). It is possible to define numerous masks e.g.
#define BIT_0 0x1 // or 1 << 0
#define BIT_1 0x2 // or 1 << 1
#define BIT_2 0x4 // or 1 << 2
#define BIT_3 0x8 // or 1 << 3
etc...
This gives you:
bit = char & BIT_1;
You can use these definitions in the above code to sucessfully index a bit within either a macro or a function.
To set a bit:
char |= BIT_2;
To clear a bit:
char &= ~BIT_3
To toggle a bit
char ^= BIT_4
This help?
Individual bits can be indexed as follows.
Define a struct like this one:
struct
{
unsigned bit0 : 1;
unsigned bit1 : 1;
unsigned bit2 : 1;
unsigned bit3 : 1;
unsigned reserved : 28;
} bitPattern;
Now if I want to know the individual bit values of a var named "value", do the following:
CopyMemory( &input, &value, sizeof(value) );
To see if bit 2 is high or low:
int state = bitPattern.bit2;
Hope this helps.
There is a standard library container for bits: std::vector. It is specialised in the library to be space efficient. There is also a boost dynamic_bitset class.
These will let you perform operations on a set of boolean values, using one bit per value of underlying storage.
Boost dynamic bitset documentation
For the STL documentation, see your compiler documentation.
Of course, you can also address the individual bits in other integral types by hand. If you do that, you should use unsigned types so that you don't get undefined behaviour if decide to do a right shift on a value with the high bit set. However, it sounds like you want the containers.
To the commenter who claimed this takes 32x more space than necessary: boost::dynamic_bitset and vector are specialised to use one bit per entry, and so there is not a space penalty, assuming that you actually want more than the number of bits in a primitive type. These classes allow you to address individual bits in a large container with efficient underlying storage. If you just want (say) 32 bits, by all means, use an int. If you want some large number of bits, you can use a library container.

Resources