Я пытаюсь повернуть boost::dynamic_bitset
в string
так что я могу передать его функции сжатия. Я могу конвертировать его с помощью boost::to_string
но это приводит к увеличению в 8 раз. Когда я возвращаюсь из string
в boost::dynamic_bitset
, это не уменьшает 8-кратное количество используемых битов, что решило бы мою проблему, поскольку это привело бы к тому, что общий объем используемого пространства был бы в конечном счете оригинальным количеством сжатых битов.
Я с нетерпением жду, чтобы остановить 8-кратное увеличение при переходе от boost::dynamic_bitset
-> string
или уменьшите занимаемое пространство в 8 раз при переходе от boost::dynamic_bitset
-> string
,
Данные хранятся в boost::dynamic_bitset
исходит из двоичного файла. Вот тот, который я использую, но теоретически любой файл с двоичными данными должен работать.
При выводе количества бит звоню string.size()
который возвращает размер в байтах, поэтому я умножаю на 8. boost::dynamic_bitset.size()
возвращает размер в терминах битов, поэтому мой вывод должен сравнивать яблоки с яблоками, предполагая, что все правильно.
Вот результат, который я сейчас получаю:
Dynamic bitset input bits = 6431936
String from dynamic_bitset bits = 51455488
Dynamic bitset from string bits = 51455488
Вот мой код:
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <boost/dynamic_bitset.hpp>
#include <boost/math/cstdfloat/cstdfloat_types.hpp>
#include <boost/numeric/conversion/cast.hpp>
typedef boost::float32_t float32;
typedef boost::uint32_t uint32;
int main() {
std::vector<unsigned char> data;
unsigned char *cp;
float32 value = 8.0;
boost::uint32_t internal;
std::memcpy( &internal , &value , sizeof( value ) );
std::ifstream fin("ex.bin", std::ios::binary);
while (fin.read(reinterpret_cast<char*>(&internal), sizeof(uint32))) {
std::memcpy( &value, &internal , sizeof( internal ) );
cp = (unsigned char *)&internal;
for(int i = 0; i < 4; ++i) {
data.push_back(*cp);
++cp;
}
}
boost::dynamic_bitset<unsigned char> bitset;
std::string buffer;
bitset.init_from_block_range(data.begin(), data.end());
std::cout << "Dynamic bitset input bits = " << bitset.size() << "\n";
boost::to_string(bitset, buffer);
std::cout << "String from dynamic_bitset bits = " << buffer.size()*8 << "\n";
boost::dynamic_bitset<unsigned char> from_str(buffer.begin(), buffer.end());
std::cout << "Dynamic bitset from string bits = " << from_str.size() << "\n";
return 0;
}
size()
Метод в контейнерах C ++ идиоматически относится к количеству элементов, а не к количеству байтов.
std::string::size()
дает вам счет char
значения в строке, в то время как boost::dynamic_bitset::size()
возвращает количество биты хранится в нем; как вы его инициализировали из n =buffer.size()
«блоки» по 8 бит каждый (char
на 8 битах практически на любой «нормальной» платформе), вполне ожидаемо, что возвращаемый размер будет в 8 раз больше, в то время как фактическая потребляемая память точно такая же.
редактировать: после последней модификации проблема теперь совершенно иная.
boost::to_string
не выводит внутреннее компактное представление, но генерирует удобочитаемую строку из фактического '0'
а также '1'
символов, что приводит к увеличению требуемого размера в 8 раз (на выходе получается последовательность из 8-битных байтов, из которых эффективно используется только один бит).
Других решений пока нет …