1

Is there a way to extract a CPU word size long subsequence of bits from a bitset efficiently without iterating over each bit individually? Something like

#include <bitset>
#include <iostream>

using namespace std;

int main() {
        bitset<100> b;
        // Do something with b
        // ...

        // Now i want sizeof(long) many bits starting at position 50
        unsigned long l = (b>>50).to_ulong();
}

would do if it would truncate the bitstring instead of throwing an exception!

barbaz
  • 1,642
  • 2
  • 17
  • 27

2 Answers2

4

You could create a constant bitset mask that only has the bottom N bits set, eg like this:

bitset<100> const mask((unsigned long) -1);

Then you can do ((b >> 50) & mask).to_ulong() to extract the bits. If your definition of "word" isn't the same as unsigned long, a different mask will be needed.

(I changed your left shift to a right shift, which I believe will work better.)

A sufficiently smart compiler could convert this to just a shift and reading out the result; I doubt whether any compilers are actually sufficiently smart. But I suspect the cost of the shift outweighs the cost of the and anyway.

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64
  • Oh my! Indeed the exception is only thrown if bits higher than sizeof(unsigned long) are set! I had concluded that the exception is thrown for every bitset with n>sizeof(unsigned long). Thanks! – barbaz Jun 05 '11 at 16:27
0

New info on comments make this answer irrelevant.

The answer needs a question: What basic datatype is your bitset made from? Assuming the said bitset is stored lsb to msb on an lsB to msB array of unsigned chars, then:

1) the byte index holding bit X is found by X/8;

2) the bit index at byte (X/8), is found by X%8;

After X%8 -1 left shifting of that unsigned char you have the lsb of the resulting unsigned long and the next 8-X%8 bits. Because the shift operator operated on a single unsigned char, you'll need further code to copy to the next 3 (or 4) unsigned chars) into an auxiliary short/long, then or-copy to the result the relevant bits that will make the full unsigned long.

jpinto3912
  • 1,457
  • 2
  • 12
  • 19
  • I am talking about std::bitset. That support the subscript [] operator, hence the arithmetic that you describe there is already implemented. I'm looking for a solution to extract a max. CPU word size long word with say at most 2 shift operations + AND internally (which would be possible i guess) - but i dont see that the std::bitset frontent supports that. using the subscript operator to do a bit-wise copy is not the solution i'm looking for, each [] call returns a bool. – barbaz Jun 04 '11 at 14:36