Bitwise OR of constants
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),
kCFCalendarUnit开发者_开发技巧Year = (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.
精彩评论