I started reading "Programming Pearls" today and while doing it's exercise I came across this question "How would you implement your own bit vector?". When I looked at the solution it was like this:
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N/BITSPERWORD];
void set(int i) { a[i >> SHIFT] |= (1 << (i & MASK));
Where I am getting confused at is this statement
1 << (i & MASK)
Could someone please explain me what's going on here?
Note that MASK
is set such that it has the lowest SHIFT
bits set, where SHIFT
is exactly the base-2 logarithm of BITSPERWORD
.
Therefore (i & MASK)
will select the lowest 5 bits of i
, which is the same as taking the remainder after dividing by 32 (just consider how taking the lowest two digits of a decimal number gives you the remainder after dividing by 100, for example). That gives the number of the bit within a word we're interested in.
1 << (i & MASK))
(which is, by the way, an expression, not a statement) now creates a value where exactly the bit we're interested in is set. Merging this value into the memory word with |=
will set the desired bit of the bit vector.
0x20 is 32, so i & 0x1F
takes i
modulo 32, so that you never shift by 32 bits. This is a safeguard because shifting by anything that isn't strictly less than the size of the type is undefined behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With