比特集是如何真正工作的
How do bitsets really work
我在SRT模拟器上工作,在实现中使用std::bitset<size>
。我以为我很了解它们,直到我做到了:
template <unsigned int larger, unsigned int smaller>
bitset<smaller> Partition(const bitset<larger> &original, unsigned int offset) {
return bitset<smaller>(original.to_ulong() >> offset);
}
template <unsigned int larger, unsigned int smaller>
void Partition(bitset<larger> &location, const bitset<smaller> &value, unsigned int offset) {
location <<= offset;
location ^= bitset<larger>(value.to_ulong());
return;
}
第一个函数被设计为取一个较长的数字,并将特定数量的比特划分为一个较短的数字。例如,如果我有10111010
,而我只想在std::bitset<4>
中使用1011
,那么我将调用Partition<8, 4>(my_larger_number, 4);
。第二种则相反。我可以取一个较短的数字,然后把它变成一个较长的数字。这两个功能都按预期工作,直到:
int main() {
bitset<16> A("1011101010011000");
cout << "A = " << A << endl;
bitset<4> Bs[4];
bitset<16> C;
for (int i = 0; i < 4; i++) {
Bs[i] = Partition<16, 4>(A, 4 * i);
cout << "B[" << i << "] = " << Bs[i] << endl;
}
for (int i = 3; i >= 0; i--) {
cout << "Value of B[" << i << "] = " << bitset<16>(Bs[i].to_ulong()) << endl;
Partition<16, 4>(C, Bs[i], 4);
cout << "C = " << C << endl;
}
return 0;
}
此操作的输出为:
A = 1011 1010 1001 1000
B[0] = 1000
B[1] = 1001
B[2] = 1010
B[3] = 1011
Value of B[3] = 0000 0000 0000 1011
C = 0000 0000 0000 1011
Value of B[2] = 0000 0000 1011 1010
C = 0000 0000 0000 1010
Value of B[1] = 0000 1011 1010 1001
C = 0000 1011 0000 1001
Value of B[0] = 1011 1010 1001 1000
C = 0000 1010 0000 1000
从本质上讲,发生的事情是,即使在比特集变短后,比特集也会以某种方式保存额外的信息比特,然后每次调用Partition<16, 4>(C, Bs[i], 4)
时,它们都会被推回到C
上。但是,我的问题是,为什么?这些值不应该保存在内存中,即使它们是,每次调用Bs[i] = Partition<16, 4>(A, i * 4)
时我都会创建新的对象,所以这些值不应出现。
任何解释都会有帮助。
感谢对我最初帖子的有益评论,我发现问题不在于std::bitset
的C++实现,而是我用来编译它的Xcode g++中的一些奇怪现象。为了解决这个问题,我创建了Partition
:的修改版本
template <unsigned int larger, unsigned int smaller>
bitset<smaller> Partition(const bitset<larger> &original, unsigned int offset) {
bitset<smaller> newValue(0);
newValue = ((original >> offset) & bitset<larger>((1 << smaller) - 1)).to_ulong();
return newValue;
}
本质上,我所做的只是屏蔽第一个smaller
位,然后使其他位为0。我宁愿不这样做,因为它增加了复杂性,但它似乎是唯一可用的解决方案,而不知道Xcode是如何做到这一点的。
相关文章:
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- Python中的for循环与C++有何不同
- 为什么我的 std::ref 无法按预期工作?
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- opengl32.lib如何在Windows(仅1.1版本)上工作?它是否真正实现了OpenGL函数
- 当 int 方法工作正常时,void 方法有何不同,或者为什么我不能调用 void 方法?
- 互斥是如何真正工作的
- 软件或防病毒产品的试用版如何真正工作
- 为什么具有真正价值enable_if似乎与直接放置空白的工作方式不同
- 我包括了“SDL_TTF.h”.我还应该对SDT真正类型的字体工作做些什么
- 比特集是如何真正工作的
- 当代码在没有真正更改的情况下意外地开始工作时