descriptor = limit & 0x000F0000;
descriptor |= (flag << 8) & 0x00F0FF00;
descriptor |= (base >> 16) & 0x000000FF;
descriptor |= base & 0xFF000000;
I understood the fact that the and operation is used for masking certain bits. But what is OR operation used here for??? Please elaborate.
This is part of the code for creating a Global Descriptor Table.
If you look at just a single bit, the truth table is given by
0 | 0 == 0
0 | 1 == 1
1 | 0 == 1
1 | 1 == 1
So, bitwise or sets a bit if and only if that bit is set in at least one of the operands.
When you use bitwise or on a variable with more that a single bit, the above truth table is applied in a bitwise fashion.
So, suppose that you had two variables whose binary representations were
001101
011001
When you combine them with bitwise or, you collect all the bits that are set in either variable. So the result is
011101
The bitwise or operator is commonly used to add new flags to a set of bit flags. The value is used to represent a mathematical set. Each bit is assigned a particular meaning, that is associated with a member of the universal set. When the bit is 1, that member is included in the set, and when the bit is 0, the associated member is not in the set.
So, let us have a very simple example with a universal set having two members. Let us call the variable, controlState. Bit 0 represents the visible property, and bit 1 represents the enabled property. So, you can define flags like so
const int visibleFlag = 1; // 01 in binary
const int enabledFlag = 2; // 10 in binary
Then you can build the controlState variable like this:
int controlState = 0; // empty set
if (isVisible)
controlState |= visibleFlag;
if (isEnabled)
controlState |= enabledFlag;
It gets more interesting if you don't know whether or not a particular bit is set. So, you can ensure that the visible bit is set like this:
controlState = ...; // could set visible flag, or not ...
controlState |= visibleFlag;
It does not matter whether the original value of controlState included the flag or not. After this operation, it will be set for sure, and no other flags altered.
This is what is happening in your code example. So,
descriptor = limit & 0x000F0000;
initializes descriptor. Then
descriptor |= (flag << 8) & 0x00F0FF00;
adds (flag << 8) & 0x00F0FF00. And so on.
What the code you've shown is doing is constructing descriptor by selecting different parts of it from other boolean expressions.
Notice that the constants that (flag << 8), (base >> 16) and base are being ANDed with, when themselves ORed together, produce 0xFFFFFFFF.
The point of the OR is to say, "the first 8 bits come from (base >> 16), the next 8 bits from flag << 8, the next 4 from limit, the next 4 from flag << 8 and the last 8 from base." So finally, descriptor looks like this:
d[7], d[6], b[5], a[4], b[3], b[2], c[1], c[0]
Where each comma separated variable is a hexadecimal digit, and a, b, c, and d are
limit, (flag << 8), (base >> 16) and base respectively. (The commas are just there for readability, they stand for concatenation of the digits).
The use of |= here is essentially short hand for the following
descriptor = destriptor | ((flag << 8) & 0x00F0FF00);
descriptor is a collection of values packed together as bitfields. This code is building it up from four values (limit, flag, and two parts of base). Each step is shifting the value to the correction bit position and then ANDing with a mask to ensure the bits don't spill over into other positions. The A |= B operator expands to A = A | B and merges together all of the individual results. This could also be done using a struct with bitfields, although perhaps with less portability.
Bit-wise OR | operator (copies a bit if it exists in either operand) used here to ORing the descriptor with right hand operator of = and store the result to descriptor. It is equivalent to
descriptor = descriptor | (flag << 8) & 0x00F0FF00;
Truth table fo OR operation:
For x = 1 1 0 0 and Y = 1 0 1 0 OR operation works as follows:
Related
I want to verify two bits (for example the bit number 3 and 5) values of a uint8
if their value is 0, I want to return 1
uint8 a;
if ((a & !(1<<3)) && (a & !(1<<5)))
{
Instructions..
}
Is this code correct ?
No, your code won't work in way that you want. ! operator results only in 0 or 1 and info about actual non-zero bit is lost anyway. You may use something like this:
if(!(a & ((1 << 3) | (1 << 5))) {
/* ... */
}
At first stage you are creating mask with | operator. This mask has non-zero bits only at positions that you are interested in. Then this mask is combined with tested value via &. As result you get 0 only if value has zero bits at tested positions. And then just inverse 0 to 1 with ! to obtain true condition.
It is not correct.
The ! operator is boolean NOT, not a bitwise NOT.
So, if you want to check if bits 3 & 5 are both zeroes you should write:
uint8 a;
...
if (!(a & (1<<3)) && !(a & (1<<5)))
{
Instructions..
}
Further optimisation of the expression in if is possible.
This is trivial if you don't attempt to write it as a single, messy expression. There is no advantage of doing so - contrary to popular belief, mashing as many operators into a single line is actually very bad practice. It destroys readability and you gain no performance benefits what-so-ever.
So start by creating a bit mask:
uint8_t mask = (1<<3) | (1<<5);
(The parenthesis are actually not needed, but not everyone can cite the C operator precedence table in their sleep, so this is recommended style.)
Then check the data against the mask:
if(data & mask) // if any bit contains value 1
return 0;
else // if no bit contains value 1
return 1;
Which, if you will, can be rewritten as a boolean expression:
return !(data & mask);
The complete function could look like this:
bool check_bits (uint8_t data)
{
uint8_t mask = (1<<3) | (1<<5);
return !(data & mask);
}
Your expression is false, you should not negate the masks this way and you must ignore other bits so don't use a negation. Simply:
(a & (1<<3)) + (a & (1<<5))
gives 0 if both are 0s.
Assuming that a actually is initialized, then the expression will not work as you expect. The logical not operator ! gives you a one or a zero (boolean true or false), which you then use in a bitwise and operation. That will not give you the correct result.
I suppose you mean to use the bitwise complement operator ~ instead, as in ~(1 << 3). Not that it would work anyway, as that will just check that any of the other bits in a is non-zero.
Instead check if the bit is one, and then turn around the logic using the logic not operator !, as in !(a & 1 << 3).
No. ! operator does logical negation, and since 1<<3 is not zero, !(1<<3) is zero. It means a & !(1<<3) will always be zero and therefore the condition will never be true.
I think masking is one of good ways to do what you want to do.
uint8 a;
/* assign something to a */
return (a & ((1 << 3) | (1 << 5))) == 0;
a & ((1 << 3) | (1 << 5)) is a value in which the 3rd and 5th bit (0-origin) of a keep their original value and all other bits is turned to zero. Checking if the value is zero means checking if all of the bits to check are zero while not careing other bits. == operator will return 1 if two operands are equal and 0 otherwise.
If you want to test for some combination of BIT_A and BIT_B (or whatever number of bits you can have) You can do this:
#define BIT_A (1 << 3)
#define BIT_B (1 << 5)
...
#define BIT_Z (1 << Z)
...
/* |here you put all bits |here you put only the ones you want set */
/* V V */
if (a & (BIT_A | BIT_B | ... | BIT_Z) == (BIT_A | ... | BIT_I | ...))
{
/* here you will know that bits BIT_A,..., BIT_I,... will **only**
* be set in the mask of (BIT_A | BIT_B | ... | BIT_Z) */
}
as with a & (BIT_A | BIT_B | ... ) you force all bits not in the set to be zero, so only the bits in the set will conserve their values. With the second mask, you generate a bitmap with only the bits of the set you want to be set (and of course the bits that are not in the set forced zero) so if you compare both values for equalness, you'll get the expected result.
NOTE
As an answer to your question, the particular case in which you want all the bits equal to one, is to make both masks equal. For your case, you want to check if both bits are zero, then your test is (the second mask has no bits set, so it is zero):
if (a & ((1 << 3) | (1 << 5)) == 0) { ...
(All bits in the second mask are zero as the required mask, and both, the third and the fifth bits are set in the first mask) This can be written in a more compact form as (you can see it written as):
if (!(a & 0x28)) { /* 0x28 is the octal for 00101000, with the bits you require */
WHY THE CODE YOU WROTE IS NOT CORRECT
First you mix logical operators like ! with bitmasks, making !(1<<3)to eval to 0 (1<<3 is different of 0 so it is true, negating gives 0) and the same for the !(1<<5) subexpression. When you mask a with those values makes you get a & 0 ==> 0 and a & 0 ==> 0 and anding both together gives 0 && 0 ==> 0. So the result value of your expression is 0 -- false always, independent of the original value of a.
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.
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.
While reading some documentation here, I came across this:
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
I have no idea how this works. I read up on the bitwise operators in C, but I do not understand how you can fit three (or more!) constants inside one int and later being able to somehow extract them back from the int? Digging further down the documentation, I also found this, which is probably related:
typedef enum {
kCFCalendarUnitEra = (1 << 1),
kCFCalendarUnitYear = (1 << 2),
kCFCalendarUnitMonth = (1 << 3),
kCFCalendarUnitDay = (1 << 4),
kCFCalendarUnitHour = (1 << 5),
kCFCalendarUnitMinute = (1 << 6),
kCFCalendarUnitSecond = (1 << 7),
kCFCalendarUnitWeek = (1 << 8),
kCFCalendarUnitWeekday = (1 << 9),
kCFCalendarUnitWeekdayOrdinal = (1 << 10),
} CFCalendarUnit;
How do the (1 << 3) statements / variables work? I'm sorry if this is trivial, but could someone please enlighten me by either explaining or maybe posting a link to a good explanation?
Basically, the constants are represented just by one bit, so if you have a 32 bit integer, you can fit 32 constants in it. Your constants have to be powers of two, so they take only one "set" bit to represent.
For example:
#define CONSTANT_1 0x01 // 0001 in binary
#define CONSTANT_2 0x02 // 0010 in binary
#define CONSTANT_3 0x04 // 0100 in binary
then you can do
int options = CONSTANT_1 | CONSTANT_3; // will have 0101 in binary.
As you can see, each bit represents that particular constant. So you can binary AND in your code and test for the presence of each constant, like:
if (options & CONSTANT_3)
{
// CONSTANT_3 is set
}
I recommend you to read about binary operations (they work like LOGICAL operators, but at the bit level), if you grok this stuff, it will make you a bit better of a programmer.
Cheers.
If you look at a number in binary, each digit is either on (1) or off (0).
You can use bitwise operators to set or interrogate the individual bits efficiently to see if they are set or not.
Take the 8 bit value 156. In binary this is 10011100.
The set bits correspond to bits 7,4,3, and 2 (values 128, 16, 8, 4). You can compute these values with 1 << (position) rather easily. So, 1 << 7 = 128.
The number 1 is represented as 00000000000000000000000000000001
(1 << n) means shift the 1 in 1's representation n places to the left
So (1 << 3) would be 00000000000000000000000000001000
In one int you can have 32 options each of which can be turned on or off.
Option number n is on if the n'th bit is 1
1 << y is basically the same thing as 2 to the power of y
More generally, x << y is the same thing as x multiplied by 2 to the power of y.
In binary x << y means moving all the bits of x to the left by y places, adding zeroes in the place of the moved bits:
00010 << 2 = 01000
So:
1 << 1 = 2
1 << 2 = 4
1 << 3 = 8
...
<< is the shift left operator, it shifts the bits of the first operand left by the number of positions specified in the right operand (with zeros coming into the shifted positions from the right).
In your enum you end up with values that eacg have a different bit set to 1, so when you construct something like unitDate, you can later find out which flags it contains by using the & operator, e.g. unitDate & NSMonthCalendarUnit == NSMonthCalendarUnit will be true.
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.