如何将位序列放入字节(C / C ++)

时间:2012-03-10 15:01:19

标签: c++ c byte sequence bit

我有几个整数,例如(在二进制表示中):

00001000,01111111,10000000,00000001

我需要将它们按顺序放入字节数组(字符串),而不是前导零,如下所示:

10001111 11110000 0001000

我知道必须通过使用<<,>>进行位移来完成。并使用二进制或|。但是我找不到正确的算法,你能建议最好的方法吗?

我需要放置的整数是无符号长long整数,因此一个长度可以是1到8个字节(64位)。

4 个答案:

答案 0 :(得分:4)

您可以使用std::bitset

#include <bitset>
#include <iostream>

int main() {
    unsigned i = 242122534;
    std::bitset<sizeof(i) * 8> bits;
    bits = i;
    std::cout << bits.to_string() << "\n";
}

答案 1 :(得分:1)

毫无疑问其他方法可以做到,但我可能会选择最简单的方法:

std::vector<unsigned char> integers; // Has your list of bytes
integers.push_back(0x02);
integers.push_back(0xFF);
integers.push_back(0x00);
integers.push_back(0x10);
integers.push_back(0x01);
std::string str;                     // Will have your resulting string
for(unsigned int i=0; i < integers.size(); i++)
    for(int j=0; j<8; j++)
        str += ((integers[i]<<j) & 0x80 ? "1" : "0");
std::cout << str << "\n";
size_t begin = str.find("1");
if(begin > 0) str.erase(0,begin);
std::cout << str << "\n";

我在你提到你使用了很长时间或者诸如此类的东西之前写了这个,但实际上并没有改变这一点。掩码需要改变,j循环变量,否则上面应该有效。

答案 2 :(得分:0)

将它们转换为字符串,然后删除所有前导零:

#include <iostream>
#include <sstream>
#include <string>
#include <cstdint>

std::string to_bin(uint64_t v)
{
   std::stringstream ss;

   for(size_t x = 0; x < 64; ++x)
   {
       if(v & 0x8000000000000000)
          ss << "1";
       else
          ss << "0";

        v <<= 1;
   }

   return ss.str();
}

void trim_right(std::string& in)
{
   size_t non_zero = in.find_first_not_of("0");

   if(std::string::npos != non_zero)
      in.erase(in.begin(), in.begin() + non_zero);
   else
   {
       // no 1 in data set, what to do?
       in = "<no data>";
   }
}

int main()
{
  uint64_t v1 = 437148234;
  uint64_t v2 = 1;
  uint64_t v3 = 0;

  std::string v1s = to_bin(v1);
  std::string v2s = to_bin(v2);
  std::string v3s = to_bin(v3);

  trim_right(v1s);
  trim_right(v2s);
  trim_right(v3s);

  std::cout << v1s << "\n"
            << v2s << "\n"
            << v3s << "\n";

  return 0;
}

答案 3 :(得分:0)

一个简单的方法是使用“当前字节”(以下为acc),其中相关的已用位数(bitcount)和完全处理的字节向量({{ 1}}):

output

请注意,在处理结束时,您应该检查累加器中是否还有任何位(int acc = 0; int bitcount = 0; std::vector<unsigned char> output; void writeBits(int size, unsigned long long x) { while (size > 0) { // sz = How many bit we're about to copy int sz = size; // max avail space in acc if (sz > 8 - bitcount) sz = 8 - bitcount; // get the bits acc |= ((x >> (size - sz)) << (8 - bitcount - sz)); // zero them off in x x &= (1 << (size - sz)) - 1; // acc got bigger and x got smaller bitcount += sz; size -= sz; if (bitcount == 8) { // got a full byte! output.push_back(acc); acc = bitcount = 0; } } } void writeNumber(unsigned long long x) { // How big is it? int size = 0; while (size < 64 && x >= (1ULL << size)) size++; writeBits(size, x); } ),并且在这种情况下应该通过执行bitcount > 0来清除它们。

另请注意,如果速度是一个问题,那么可能使用更大的累加器是一个好主意(但输出将取决于机器的字节顺序),并且发现一个数字中使用了多少位可以比一个更快C ++中的线性搜索(例如x86有一个特殊的机器语言指令output.push_back(acc);专用于此)。