Reputation: 936
This question is asked on Pearls of programming Question 2. And I am having trouble understanding its solution.
Here is the solution written in the book.
#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)); }
void clr(int i) { a[i>>SHIFT]&=~(1<<(i & MASK)); }
int test(int i) { return a[i>>SHIFT]&(1<<(i & MASK)); }
I have ran this in my compiler and I have looked at another question that talks about this problem, but I still dont understand how this solution works.
Why does it do a[i>>SHIFT]? Why cant it just be a[i]=1; Why does i need to shifted right 5 times?
Upvotes: 3
Views: 1193
Reputation: 14379
Divide the 32 bits of int i (starting form bit 0 to bit 31) into two parts.
Since every int in a[] is 32 bits, it can keep track of 32 ints with those 32 bits. We divide every input i with 32 to find the int in a[] that is supposed to keep track of this i.
Every time a number is divided by 2, it is effectively right shifted once. To divide a number by 32, you simply right shift it 5 times. And that is exactly what we get by filtering out the first part.
How to get the first part? Right shifting i by 5 (i.e. i >> SHIFT).
How to get the second part? Do bitwise AND of i by 11111. (11111)2 = 0x1F, defined as MASK. So, i & MASK
will give the integer value represented by the last 5 bits of i.
The last 5 bits tell you how many bits to go inside the number in a[]. For example, if i is 5, you want to set the bit in the index 0 of a[] and you specifically want to set the 5th bit of the int value a[0].
Index to set = 5 / 32 = (0101 >> 5) = 0000 = 0.
Bit to set = 5th bit inside a[0]
Setting the bit for given i
1
a total of i % 32 times to the left i.e. 1 << (i & 0x1F)Getting/Testing the bit for given i
Clearing the bit for given i: It means setting the bit for that i to 0.
Upvotes: 2
Reputation: 126203
32 is 25, so a right-shift of 5 bits is equivalent to dividing by 32. So by doing a[i>>5]
, you are dividing i
by 32 to figure out which element of the array contains bit i
-- there are 32 bits per element.
Meanwhile & MASK
is equivalent to mod 32, so 1<<(i & MASK)
builds a 1-bit mask for the particular bit within the word.
Upvotes: 3