Bitwise OR of constants - c

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.

Related

Can anyone explain this bitwise function to compute log(n)

int howManyBits(int x) {
int concatenate;
int bias;
int sign = x >> 31; //get the sign
x = (sign & (~x)) | (~sign & x);
concatenate = (!!(x >> 16)) << 4;
concatenate |= (!!(x >> (concatenate + 8))) << 3;
concatenate |= (!!(x >> (concatenate + 4))) << 2;
concatenate |= (!!(x >> (concatenate + 2))) << 1;
concatenate |= x >> (concatenate + 1);
bias = !(x ^ 0);
return concatenate + 2 + (~bias + 1);
}
This code is presented as a way to calculate the minimum number of bits required to represent an integer n in 2's complement, with the assumption that the int data type is represented with 32 bits. Right shifting is assumed to be arithmetic.
I understand that the basic method is to take the log base 2 of n, round it up, and then add 1 bit to account for the sign bit.
I also understand that left-shifting is equivalent to multiplying by 2 and that right-shifting is equivalent to dividing by 2.
That being said, without comments I can't decipher what this code is doing beyond the portion where it obtains the value of the sign bit. I worked through it on pencil and paper with a sample int of the value 5 - the code works, but I don't understand why.
Could someone provide some intuitive breakdown of what the code is doing?
This code could use some comments.
This leaves x as it is if it is positive or takes the one's complement if negative. This allows the calculation to search for the most significant one regardless of positive or negative
x = (sign & (~x)) | (~sign & x);
I think the following would have been more clear:
x = sign ? ~x : x;
Next is a search for the highest 1 bit done with a binary search. First the top half of the word is searched.
concatenate = (!!(x >> 16)) << 4;
If the top half has a 1, then the result is 16. The 16 is used later both as part of the answer, but also to determine where to search next. Since it is used in the shifts that follow it will cause the following tests to either be done with the top half of the board or the bottom half.
The following concatenate operations are searching in a progressively smaller piece of the original number looking is the most significant one in the upper 8 bits or the lower 8 bits of the 16 bits that was chosen, then the upper 4 bits or the lower 4 bits of the 8 bits that was chosen, and so forth.
concatenate |= (!!(x >> (concatenate + 8))) << 3; // Check which 8 bits
concatenate |= (!!(x >> (concatenate + 4))) << 2; // Check which 4 bits
concatenate |= (!!(x >> (concatenate + 2))) << 1; // Check which 2 bits
concatenate |= x >> (concatenate + 1); // Check which 1 bit
The bias is just checking is the number 0 or not. It is 1 only if x is 0. I don't understand the need for the XOR operator.
Finally the pieces are added together.

C - function arguments and "<<" operator

i'm sorry for title for being not spesific but i dont know how it's called. here is my question: in this code snippet, there is constants defined like this:
#define WS_NONE 0
#define WS_RECURSIVE (1 << 0)
#define WS_DEFAULT WS_RECURSIVE
#define WS_FOLLOWLINK (1 << 1) /* follow symlinks */
#define WS_DOTFILES (1 << 2) /* per unix convention, .file is hidden */
#define WS_MATCHDIRS (1 << 3) /* if pattern is used on dir names too */
and there is a function defined like this:
int walk_recur(char *dname, regex_t *reg, int spec)
he sends constants(WS_DEFAULT and WS_MATCHDIRS) to function using "|":
walk_dir(".", ".\\.c$", WS_DEFAULT|WS_MATCHDIRS);
this is how he uses the arguments:
if ((spec & WS_RECURSIVE))
walk_recur(fn, reg, spec);
if (!(spec & WS_MATCHDIRS)) continue;
if WS_RECURSIVE passed to function, first if statement will be true. i didn't get how << operator works and how (spec & WS_RECURSIVE) statement returning true. and how can he sends different constants with "|"? and he can use "spec" value, which must be equal to passed constants, how is that possible?
and sorry for my bad english.
It's a very common idiom for treating a single integer value as a collection of individual bits. C doesn't have direct support for bit arrays, so we use bitwise operators to set and clear the bits.
The << operator is a left-shift operator. For example:
1 << 0 == 1
1 << 1 == 2
1 << 2 == 4
1 << 3 == 8
1 << n for any non-negative n (within range) is a power of 2. Each bit in an an integer value represents a power of 2. Any integer value can be treated as a unique sums of powers of 2.
| is the bitwise or operator; it's use to combine multiple 1-bit values (powers of 1) into an integer value:
(1 << 0) | (1 << 3) == 1 | 8
1 | 8 == 9
Here we combine bit zero (representing the value 1) and bit three (representing the value 8) into a single value 9. (We could have used + rather than | in this case, but in general using | avoids problems when some power of 2 is given more than once.)
Now we can test whether a bit is set using the bitwise and operator &:
int n = (1<<0) | (1<<3);
if (n & (1<<3)) {
printf("Bit 3 is set\n");
}
else {
printf("Bit 3 is not set\n");
}
Now we can define macros so we don't have to write 1<<0 and 1<<3 all over the place:
#define WS_RECURSIVE (1 << 0)
...
#define WS_MATCHDIRS (1 << 3)
int n = WS_RECURSIVE | WS_MATCHDIRS;
// n == 9
if (n & WS_RECURSIVE) {
// the WS_RECURSIVE bit is set
}
if (!(n&WS_MATCHDIRS) {
// the WS_MATCHDIRS bit is *not* set
}
You could also define macros to simplify setting and testing bits (SET_BIT(), IS_SET(), etc.), but most C programmers don't bother to do so. Symbolic names for the bit values are important for code readability, but once you understand how the bitwise operators work, and more importantly how the common idioms for setting, clearing, and testing bits are written, the raw operators are readable enough.
It's usually better to use unsigned rather than signed integer types; the behavior of the bitwise operators on signed types can be tricky in some cases.
The << operator is a bitwise left shift.
For example, 1 << 0 translates to 1 'left shifted by' 0 bits. This is effectively a nop as 1 left shifted by 0 bits is still the value 1.
To further clarify, let's look at a bitwise representation of a number (lets say the number is a 16 bit value to illustrate)
1 -> 0b'0000000000000001
1 << 1 would be
2 -> 0b'0000000000000010
And so on.
The | operator is a bitwise or, so the WS_DEFAULT | WS_MATCHDIRS is translated to:
0b'0001 | 0b'1000
This yields the value 0b'1001 which is then passed to the walk_dir.
If you pass in WS_RECURSIVE instead, you will be doing a bitwise and (&) operation using two identical values. This will always result in a true value.
AND Truth Table
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

What is bitwise OR used here for?

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:

constructing 32 bit unsigned int in c

I am trying to construct a 32 bit binary value using an unsigned int. This is how
the 32 bit is split into parts
part 1 = 4 bit
part 2 = 2 bit
part 3 = 12 bit
part 4 = 2 bit
part 5 = 12 bit
How do i use the parts to construct 32 bit binary value (unsigned int) using
bit shifting can someone please help
(cant just shift bits... what if i want to update certain part?)
This is typical bit-shifting/bit-masking stuff. Here's how you set the initial value:
uint32_t value = ((part1 & 0xF) << 28)
| ((part2 & 0x3) << 26)
| ((part3 & 0xFFF) << 14)
| ((part4 & 0x3) << 12)
| (part5 & 0xFFF);
Each line uses a bitwise-AND (&) to clear the upper bits of each part so it doesn't overflow its allocated bit-width within the final value. For example, if part4 was 0xFF and you forgot the & 0x3 then the upper 6 bits of part4 (0xFC) would spill into the region for part3. Then the part is shifted (<<) to its final location and bitwise-OR'd (|) with the rest of the parts.
Some developers accomplish the same thing via bitfields but I don't recommend that approach due to potential portability issues.
Most (all?) of the other answers here so far have forgotten the bitwise-AND portion of the solution. Their answers will result in bugs if the part values ever exceed the specified bit width.
If you want to update a particular portion of the value, you'll need some more bit-masking via bitwise-AND and bitwise-OR. For example, to update part4 you'd do this:
value &= ~(0x3 << 12); /* Clear the part4 region */
value |= (part4 & 0x3) << 12; /* Set the part4 region to the new value */
That first line is a little tricky if you're new to bitwork in C. It says take 0x3 and shift it by 12 (result = 0x00003000), perform a bitwise-complement (result = 0xFFFFCFFF), and set value equal to itself bitwise-AND'd with that result. That's how you clear the part4 region of the value... because you're bitwise-AND'ing that region with zero the result is that region is now zero.
The second line sets the zeroed part4 region to the new value, just like we did above when setting the initial value.
You just use shifting, as you suggested:
uint32_t x = (part1 << 28)
| (part2 << 26)
| (part3 << 14)
| (part4 << 12)
| (part5);
Looks like you want this value:
part5 + (part4 << 12) + (part3 << 14) + (part2 << 26) + (part1 << 28)
(Make sure all five variables are of type uint32_t or some such.)

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