boost::dynamic_bitset<> fills in reverse order no matter what

457 Views Asked by At

I have a massive bitset representing all the bits of a 74MB file. I am using a compression algorithm to create a compressed string representation of this bitset. I need to then store that string into another dynamic bitset so that it can be decompressed later. My issue is that no matter how I try to fill the bitset from a string, it always fills in reverse order.

For simplicity's sake, let's say my compressed string is

1110001101010111011101

Here is my first attempt at filling my output dynamic bitset:

string compressed = 1110001101010111011101;
output = boost::dynamic_bitset<unsigned char> (compressed);

When I do this, my bitset turns into the reverse of the string:

   1011101110101011000111

So then I tried this:

output = boost::dynamic_bitset<unsigned char> (compressed.begin(), compressed.end());

And I get the exact same output. Next I tried using reverse iterators, and I have no idea how this is possible but it fills the bitset the exact same way:

output = boost::dynamic_bitset<unsigned char> (compressed.rbegin(), compressed.rend());

The only way I can get my bitset filled in the proper order is to do this:

for(uint i = 0; i < compressed.size(); i++)
{
    if(compressed[i] == '0') 
       output.push_back(false);
    else output.push_back(true);
}

This fills my output bitset in proper order, however it is significantly slower than using the other method (30 seconds slower with the string I am using). I can also use std::reverse to reverse the string in place then fill the bitset, but this takes a LOT of extra time. Is there any way to efficiently populate a dynamic bitset with values from a string in normal ordering? I understand why it's filled in reverse, but I am not using my bitset to represent an integer, I am using it to store data from a file so I need it to be in order. However it doesn't make sense why using reverse iterators would produce the same output.

EDIT I've screenshotted my output and the relevant portion of my code. The compressed output shows the first 6000 characters of the compressed version of my bitset, stored as a string. This string itself has no problems. Underlined in red is the line I am using to store this string in a bitset boost::dynamic_bitset output. Then, I print the first 6000 characters of the output bitset, and they are completely different. I should note that the "output" bitset is being passed into this function as a reference parameter, but is initially empty. Output

1

There are 1 best solutions below

0
On

Per documentation the std::string constructor of boost::dynamic_bitset will assign the last character of the input to the least-significant bit, which will be the bit with index 0.

Reading it back in a loop with growing index will give the original string in reverse order.

The constructors from iterators will do something completely different. They interpret each character as an integer (the character code) and will save a binary representation for each integer to the bitset.

Considering, that e.g. the stream output operator for dynamic_bitset will print the bitset starting from the highest-significant bit, I think there is no problem storing it this way. Just make sure to consider it if you use loops. Such loops should probably be avoided though, as individual-bit access will be slower than working on whole storage blocks simultaneously. Using a native block size instead of unsigned char would probably be advisable for the same reason.

If you really need to store in the other order reverse your string first:

std::reverse(compressed.begin(), compressed.end());