如何将位序列放入字节(C/C++)
How to put bit sequence into bytes (C/C++)
我有几个整数,例如(以二进制表示):
000010000111111100000000000000 1
我需要把它们按顺序放在字节数组(chars)中,没有前导零,就像这样:
10001111 11110000 0001000
我理解这必须通过用<lt;,>>并使用二进制或|。但是我找不到正确的算法,你能建议最好的方法吗?
我需要放在那里的整数是无符号的长整型,所以一的长度可以是从1位到8字节(64位)的任何地方。
您可以使用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";
}
毫无疑问还有其他方法可以做到这一点,但我可能会选择最简单的方法:
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循环变量也需要更改,但除此之外,上面的内容应该有效。
将它们转换为字符串,然后擦除所有前导零:
#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;
}
一个简单的方法是拥有"当前字节"(下面的acc
)、其中使用的相关位数(bitcount
)和完全处理字节的矢量(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
)中是否还有任何位,在这种情况下,您应该通过执行output.push_back(acc);
来刷新它们。
还要注意的是,如果速度是一个问题,那么可能使用更大的累加器是一个好主意(然而输出将取决于机器端序),并且发现一个数字中使用了多少位可以比C++中的线性搜索快得多(例如,x86有一条专门用于此的特殊机器语言指令BSR
)。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 在UNIX系统中使用DIR查找文件的字节大小
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- std::当在256字节边界上写入整数时,流的奇怪行为
- 当比特(而不是字节)的顺序至关重要时的持久性
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 如何在文件中查找字节序列
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 字节到位运算符重载C++
- 在java中读取c++字节的位字段
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 字节真的是最小可寻址单元吗
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- 如何将字节数组元素替换为修改的十六进制 ASCII 符号?
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- 如何将原始字节附加到 std::vector?
- 基于字节数组生成静态范围整数值