C++ 从`std::vector<;中的位获取整数;char>`
我有一个C++ 从`std::vector<;中的位获取整数;char>`,c++,bytearray,bit-manipulation,bit,bit-shift,C++,Bytearray,Bit Manipulation,Bit,Bit Shift,我有一个向量,我希望能够从向量中的一系列位中得到一个无符号整数。例如 我似乎无法编写正确的操作来获得所需的输出。我预期的算法如下所示: 和第一个字节带有(0xff>>左侧字节中未使用的位) 开始%8); 返回\u type first\u wide=first; 首先是一个有趣的问题。对于一些系统工作,我也做过类似的工作 你的字符是8位宽?还是16位?你的整数有多大?32还是64 暂时忽略向量的复杂性 把它想象成一个比特数组 你有多少位?你有8个字符 需要计算起始字符、提取位数、结束字符、
向量
,我希望能够从向量中的一系列位中得到一个无符号整数。例如
我似乎无法编写正确的操作来获得所需的输出。我预期的算法如下所示:
第一个字节带有和
(0xff>>左侧字节中未使用的位)
开始%8); 返回\u type first\u wide=first;
首先是一个有趣的问题。对于一些系统工作,我也做过类似的工作- 你的字符是8位宽?还是16位?你的整数有多大?32还是64
- 暂时忽略向量的复杂性
- 把它想象成一个比特数组
- 你有多少位?你有8个字符
- 需要计算起始字符、提取位数、结束字符、位位数和中间字符数。
- 对于第一个部分字符,您将需要按位and&键
- 对于最后一个部分字符,您需要按位and&键
- 您将需要左移>),具体取决于从哪个顺序开始
- 整数的endian值是多少
- 171/8=23//第一个字节的位置
- 171%8=第一个字符/字节中的3//位
- 8-171%8=最后一个字符/字节中的5//位
- sizeof(整数)=4
- sizeof(integer)+(171%8)>0?1:0)//要检查多少个数组位置
需要一些汇编…有一件事你肯定错过了,我认为:你在向量中索引位的方式不同于你在问题中给出的方式。也就是说,根据你概述的算法,位的顺序将类似于
呃,你的整个算法,但这一个在第一步就被遗漏了。你犯了两个主要错误。第一个是:765443210 | 1514131211098 | 232221…
应该是first_wide <<= byte_width;
括号中的值必须是要右移的字节数,这也是字节_i远离末尾的字节数。值auto byte_offset = (byte_end - byte_i) * bits_per_byte;
没有语义意义(一个是增量,另一个是索引) 代码的其余部分很好。不过,这个算法有两个问题 首先,当使用结果类型累积位时,假设左侧有多余的空间。如果右侧边界附近有设置位,并且选择范围会导致位移位,则情况并非如此。例如,尝试运行byte_width-byte_i
对于位字符串bits.get_bits<uint16_t>(11, 27);
,预期结果应该是6976,但是当前实现对于位字符串0001011 01000000
返回-1216 我在下面介绍了我的实现,它从右到左构建位字符串,将位放置在正确的位置,以避免上述两个问题:11111 011 01000000
template<class ReturnType> ReturnType get_bits(int start, int end) { int max_bits = kBitsPerByte * sizeof(ReturnType); if (end - start > max_bits) { start = end - max_bits; } int inclusive_end = end - 1; int byte_start = start / kBitsPerByte; int byte_end = inclusive_end / kBitsPerByte; // Put in the partial-byte on the right uint8_t first = bytes_[byte_end]; int bit_offset = (inclusive_end % kBitsPerByte); first >>= 7 - bit_offset; bit_offset += 1; ReturnType ret = 0 | first; // Add the rest of the bytes for (int i = byte_end - 1; i >= byte_start; i--) { ReturnType tmp = (uint8_t) bytes_[i]; tmp <<= bit_offset; ret |= tmp; bit_offset += kBitsPerByte; } // Mask out the partial byte on the left int shift_amt = (end - start); if (shift_amt < max_bits) { ReturnType mask = (1 << shift_amt) - 1; ret &= mask; } }
模板 ReturnType获取_位(int开始,int结束){ int max_bits=kBitsPerByte*sizeof(返回类型); if(结束-开始>最大字节){ 开始=结束-最大\u位; } int inclusive_end=end-1; int byte_start=start/kBitsPerByte; int byte_end=包含字节/kBitsPerByte; //输入右边的部分字节 uint8_t first=bytes_[byte_end]; 整数位的偏移量=(包括结尾%kBitsPerByte); 第一个>>=7位\u偏移量; 位u偏移量+=1; ReturnType ret=0 | first; //添加剩余的字节 对于(int i=byte\u end-1;i>=byte\u start;i--){ ReturnType tmp=(uint8_t)字节[i];
tmp这对无符号整数非常有效谢谢!我正在研究有符号整数-我不完全确定
马上就到了!我希望很快就会回来更新,或者如果我发现这是我想要的行为,给你一个记号:)这段代码似乎对get_位(14,22)的期望输出
-它返回零,而不是预期的位不起作用。获取位(0,32)
您是对的。错误是由于结果在结尾被屏蔽的方式造成的。左移将位移到不重要的位置,导致位掩码为0。我添加了一个修复。519053860746
auto byte_offset = (byte_end - byte_i) * bits_per_byte;
bits.get_bits<uint16_t>(11, 27);
bits.get_bits<int16_t>(5, 21);
template<class ReturnType> ReturnType get_bits(int start, int end) { int max_bits = kBitsPerByte * sizeof(ReturnType); if (end - start > max_bits) { start = end - max_bits; } int inclusive_end = end - 1; int byte_start = start / kBitsPerByte; int byte_end = inclusive_end / kBitsPerByte; // Put in the partial-byte on the right uint8_t first = bytes_[byte_end]; int bit_offset = (inclusive_end % kBitsPerByte); first >>= 7 - bit_offset; bit_offset += 1; ReturnType ret = 0 | first; // Add the rest of the bytes for (int i = byte_end - 1; i >= byte_start; i--) { ReturnType tmp = (uint8_t) bytes_[i]; tmp <<= bit_offset; ret |= tmp; bit_offset += kBitsPerByte; } // Mask out the partial byte on the left int shift_amt = (end - start); if (shift_amt < max_bits) { ReturnType mask = (1 << shift_amt) - 1; ret &= mask; } }