我实现了一个简单的位向量类。然而,我在理解上有一些问题,如何将数据推送到它。
在标准向量中,push_back插入新元素和末尾。一个类似的逻辑可以实现为单比特。
但是,我想以给定的精度追加数字。例如:
13 => 4bits (1101)
54 => 6bits (11 0110)
522 => 10bits (10 0000 1010)从位向量开始,以位向量开始:
x x x我可以把它从最高位(左到右)加起来,所以是为了。54@6位
x x x 11 0110或者我可以把它从最低位(从右到左)加起来,所以是为了。54@6位
x x x 0110 11对我来说,第一个选择似乎更符合逻辑。
但是,当我将对齐数522@16位加在左到右时,
x x x 0000 0010 0000 1010或者从右到左
x x x 0101 0000 0100 0000但是,在这种情况下(从右到左),当我以后想要将数据读入内存时,由于Endian的原因,它们是不正确的。如何解决这一逻辑?
我希望能够以选定的位精度追加数字,然后将它们从内存中复制到变量中。
目前,我的解决办法是:
template <typename T>
void BitVector::Append(T number, Endian e){
if (e == BitVector::Endian::Big){
this->Append(number, sizeof(T));
}
else {
uint8_t tmp[sizeof(T)];
memcpy(tmp, &number, sizeof(T));
for (size_t i = 0; i < sizeof(T); i++){
this->Append(tmp[i], 8);
}
}
}和
void BitVector::Append(uint64_t number, uint32_t bitSize){
for (long i = long(bitSize - 1); i >= 0; i--){
this->push_back((number >> i) & 1);
}
}带有小endian的模板应该对应于数组的设置元素。
BitVector bb;
bb.Append<uint16_t>(160, BitVector::Endian::Little);
bb.Append<uint16_t>(39, BitVector::Endian::Little);
uint16_t tmp[2];
tmp[0] = 160;
tmp[1] = 39;
uint8_t res[4];
memcpy(res, tmp, 4); res和位向量的内部数据现在包含相同的数据。
然而,我不确定这是否是最易读的方式。
发布于 2019-08-09 17:50:37
这里没有正确的答案。memcpy()代码使用机器的endianess重新解释位模式,并执行未定义的行为。对于位向量,您可以决定是强制执行特定的endianess,还是坚持默认的机器。这两种方法都不是正确的,这仅仅取决于您想要如何使用位向量。
一般说来,用整数扩展位向量的概念似乎有点可疑。如果您想忽略未设置的更重要的位(如示例所示,尽管Append()实现没有这样做),这也是非常奇怪的。
如果您是出于必要而不是出于兴趣而实现位向量的,请研究std::vector<bool>是否满足您的需求。它是以这样一种方式指定的,即它可以作为位向量来实现。
发布于 2019-08-09 21:02:32
您正在实现一个位数组。位位置从0向上编号。一点也不牵涉到这件事。
现在,如果将数字4添加为3位数,则可以决定要设置哪些位。如果您的向量已经包含79位,则需要添加位数79、80和81。如果按该顺序添加数字4 (0、0和1)的位0、1和2,这将是最有意义的。
我建议您使用64位无符号整数作为后备存储,并使用shift操作将所有内容放置在正确的位置。
您在绘图中所犯的一个错误:您从左到右绘制数组中的位,就像我们通常所做的那样,但是数字中的位是从右到左的。这可能是S很多困惑的根源。
https://softwareengineering.stackexchange.com/questions/395849
复制相似问题