3

I am studying a question in the book Programming Pearls, and they recommended this function to set a bit in a bit vector. I'm a bit confused at to what it does.

#define BITSPERWORD 32
#define MASK 0x1F
#define SHIFT 5
#define N 1000000

int a[1 + N/BITSPERWORD];

void set(int i){
   a[i >> SHIFT] |= (1 << (i & MASK)); 
}

Here is my (probably wrong) interpretation of this code. if i = 64,

1) first, it takes i and shifts it to the right by SHIFT (which is 5) bits. This is equivalent to DIVIDING (not multiplying, as I first thought) i by 2^5. So if i is 64, the index of a is 2 (64 / 2^5)

2) a[2] |= (1 << (64 & MASK))
64 & 1 = 1000000 & 01 = 1000001.
So 1 gets left shifted how many bits????

10
  • Right-shift is dividing by two. Commented Jul 20, 2013 at 17:01
  • This is equivalent to multiplying i by 2^5. NO This is equivalent to dividing i by 2^5. Commented Jul 20, 2013 at 17:04
  • Are you sure i is int not unsigned int ? where from you bring this code ? Commented Jul 20, 2013 at 17:06
  • Oops. OK, so I changed it to reflect dividing by 2^5. What about the rest? Commented Jul 20, 2013 at 17:06
  • 2 (64 / 2^5) ? or only (64 / 2^5) ... think, if 1000 >> 1 == 0100 so x >> 5 == x / 2^5 only Commented Jul 20, 2013 at 17:09

1 Answer 1

3
  1. It seems how this method works, even though I feel like there are better ways to set a bit. Is to find the index of the ith bit it essentially divides by 32 because that is the number of bits per word.
  2. Since the operator used here is | the function is setting the bit to one not toggling the bit
  3. 0x1F is actually 31 and when anded with the i you get the remainder (not sure why they just didn't use %)
  4. And lastly the shift takes the 1 to the proper location and or's it with the right slot in the vector.

If you are planning to use this code

  1. you could write it a lot clear without defines and using more obvious methods of doing it, I doubt it would make a difference in speed.
  2. Also you should probably just use std::bitset
  3. the use of the mask to get the remainder particularly annoyed me because I'm pretty sure it would not necessarily work for every number, 31 happens to work because it's all 1's
Sign up to request clarification or add additional context in comments.

2 Comments

+1 for clarifying 0X1F is 31.. I thought it was 1 the whole time. WOW. That clears up a lot. Thanks.
@HenleyChiu lol no problem, honestly there are much clearer ways to set a bit, I do not like this code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.