bitsets 是如何工作的

How do bitsets really work

我正在使用 SRT 模拟器,并且在我的实现中使用了 std::bitset<size>s。在我这样做之前,我认为我已经很好地理解了它们:

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

本质上,发生的事情是位集以某种方式保存了额外的信息位,即使它们已经变短了,然后每次调用 [= 时它们都会被推回 C 19=]。但是,我的问题是,为什么?这些值不应该保存在内存中,即使它们保存在内存中,我每次调用 Bs[i] = Partition<16, 4>(A, i * 4) 时都会创建新对象,所以这些值不应该显示。

任何解释都会有所帮助。

感谢对我的原始 post 的有益评论,我发现问题不在于 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 是如何做到这一点的。