首页 > 解决方案 > 如何在不使用 to_string 或逐个提取位的情况下提取大于 unsigned long long 的位集子集?

问题描述

我想从给定的位集中提取一个子集,其中:

  1. G(给定的位集大小)和S 子集大小)在编译时都是已知的

  2. G > sizeof(unsigned long long) * 8

  3. 小号 <= sizeof(int) * 8

  4. 子集可以从给定位集中的任何位置开始

  5. 结果子集应该是正确大小的位集,S


我可以使用按位数学隔离子集,但bitset.to_ullong由于溢出错误而无法工作。

我知道我可以使用bitset.to_string并进行字符串操作/转换。我目前正在做的是手动逐个提取位(这对我的用例来说已经足够了)

我只是想知道是否还有其他方法可以做到这一点。

标签: c++std-bitset

解决方案


std::bitset具有位移运算符,因此例如您可以编写一个函数将位(begin,end]放在前面:

template <size_t size>
std::bitset<size> extract_bits(std::bitset<size> x,int begin, int end) {
    (x >>= (size-end)) <<= (size-end);
    x <<= begin;
    return x;
}

例如要获取位 1 和 2:

int main()
{
    std::bitset<6> x{12};
    std::cout << x << "\n";

    std::cout << extract_bits(x,1,3);
}

输出:

001100
010000

如果你知道begin并且end在编译时你可以得到一个std::bitset只包含所需位的:

template <size_t begin,size_t end,size_t in>
std::bitset<end-begin> crop(const std::bitset<in>& x) {
    return std::bitset<end-begin>{ x.to_string().substr(begin,end-begin) };
};

auto c = crop<1,3>(x);
std::cout << c;        // 01

如果位集太大而无法放入unsigned long long我不知道另一种不使用to_string()或循环单个位的方式。


推荐阅读