Преобразование boost :: dynamic_bitset в string дает увеличение в 8 раз - PullRequest
0 голосов
/ 07 декабря 2018

Я пытаюсь превратить 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;
}

1 Ответ

0 голосов
/ 07 декабря 2018

Метод size() в контейнерах C ++ идиоматически относится к количеству элементов, а не к числу байтов.

std::string::size() дает количество char значений в строке, тогда как boost::dynamic_bitset::size() возвращает количество битов , хранящихся в нем;поскольку вы инициализировали его из n = buffer.size() «блоков» по ​​8 бит каждый (char - это 8 бит на практически любой «нормальной» платформе), вполне ожидаемо, что возвращаемый размер будет в 8 раз больше, в то время какфактически используемая память точно такая же.


Редактировать : после последней модификации проблема теперь совершенно другая.

boost::to_string не выводит внутреннее компактное представление, но генерирует удобочитаемую строку, состоящую из фактических символов '0' и '1', что приводит к увеличению требуемого размера в 8 раз (на выходе получается последовательность из 8-битных байтов)из которых эффективно используется только один бит).

...