bv-rs icon indicating copy to clipboard operation
bv-rs copied to clipboard

Creating new "Bits" with the first N bits set

Open clintonmead opened this issue 4 years ago • 1 comments

Hi, your library looks like it's largely suiting my needs to modify generic bitsets of arbitrary length, but I was just wondering if there was a way to set the first N bits of a BitsT : BitsMut object. I could go with Default::default() and set the first N bits in a loop but this approach seemed slow, especially in the case BitT was a multiword bitset. set_bits() seemed to be what I was looking by it's name but the value argument was Block, not bool so this confused me as to it's usage. Any help appreciated.

clintonmead avatar Mar 31 '20 06:03 clintonmead

The idea of set_bits is that it works a block at a time, but doesn‘t necessarily set every bit in the block to the same value. Assuming that n is less than the block size and that m is the total number of bits you want, you should be able to do something like this:

let mut bv: BitVec<Block> = BitVec::new_fill(false, m);
let all_ones: Block = !0;
bv.set_bits(0, n, all_ones);

If n exceeds the block size then you’re going to need a loop:

let mut bv: BitVec<Block> = BitVec::new_fill(false, m);

let full_blocks     = Block::div_nbits(n);
let full_block_bits = Block::mul_nbits(full_blocks);
let extra_bits      = n - full_block_bits;

let all_ones: Block = !0;

for i in .. full_blocks {
    bv.set_block(i, all_ones);
}
bv.set_bits(full_block_bits, extra_bits, all_ones);

Does that make sense?

Alternatively, if n is usually closer to m than it is to 0 and you really care, then you might want to compare the above to using BitVec::with_capacity followed by repeated calls to BitsPush::push_block.

tov avatar Mar 31 '20 20:03 tov