tags:

views:

649

answers:

3

hi.

Can you recommend efficient/clean way to manipulate arbitrary length bit array? right now I am using regular int/char bitmask, but those are not very clean when array length is greater than datatype length.

std vector<bool> is not available for me.

thanks

+5  A: 

boost::dynamic_bitset if the length is only known in run time.

std::bitset if the length is known in compile time (although arbitrary).

KennyTM
thanks. I cannot use directly (GPU device) but I can look at source code
aaa
@aaa: You can use `.to_ulong()` to get the numeric value for the device, assuming less than 32 bits.
KennyTM
runtime functions require special keywords, so I cannot use bitset directly in that sense
aaa
+1  A: 

You can use std::bitset

int main() {
  const bitset<12> mask(2730ul); 
  cout << "mask =      " << mask << endl;

  bitset<12> x;

  cout << "Enter a 12-bit bitset in binary: " << flush;
  if (cin >> x) {
    cout << "x =        " << x << endl;
    cout << "As ulong:  " << x.to_ulong() << endl;
    cout << "And with mask: " << (x & mask) << endl;
    cout << "Or with mask:  " << (x | mask) << endl;
  }
}
Brian R. Bondy
+5  A: 

Since you mention C as well as C++, I'll assume that a C++-oriented solution like boost::dynamic_bitset might not be applicable, and talk about a low-level C implementation instead. Note that if something like boost::dynamic_bitset works for you, or there's a pre-existing C library you can find, then using them can be better than rolling your own.

Warning: None of the following code has been tested or even compiled, but it should be very close to what you'd need.

To start, assume you have a fixed bitset size N. Then something like the following works:

typedef word_t uint32_t;
enum { WORD_SIZE = sizeof(word_t) * 8 };

word_t data[N / 32 + 1];

inline int bindex(int b) { return b / WORD_SIZE; }
inline int boffset(int b) { return b % WORD_SIZE; }

void set_bit(int b) { 
    data[bindex(b)] |= 1 << (boffset(b)); 
}
void clear_bit(int b) { 
    data[bindex(b)] &= ~(1 << (boffset(b)));
}
int get_bit(int b) { 
    return data[bindex(b)] & (1 << (boffset(b));
}
void clear_all() { /* set all elements of data to zero */ }
void clear_all() { /* set all elements of data to one */ }

As written, this is a bit crude since it implements only a single global bitset with a fixed size. To address these problems, you want to start with a data struture something like the following:

struct bitset { word_t *words; int nwords; };

and then write functions to create and destroy these bitsets.

struct bitset *bitset_alloc(int nbits) {
    struct bitset *bitset = malloc(sizeof(*bitset));
    bitset->nwords = (n / WORD_SIZE + 1);
    bitset->words = malloc(sizeof(*bitset->words) * bitset->nwords);
    bitset_clear(bitset);
    return bitset;
}

void bitset_free(struct bitset *bitset) {
    free(bitset->words);
    free(bitset);
}

Now, it's relatively straightforward to modify the previous functions to take a struct bitset * parameter. There's still no way to re-size a bitset during its lifetime, nor is there any bounds checking, but neither would be hard to add at this point.

Dale Hagglund