简体   繁体   English

从整数数组构造位集

[英]Construct bitset from array of integers

It's easy to construct a bitset<64> from a uint64_t : uint64_t构造bitset<64>很容易:

uint64_t flags = ...;
std::bitset<64> bs{flags};

But is there a good way to construct a bitset<64 * N> from a uint64_t[N] , such that flags[0] would refer to the lowest 64 bits? 但是,是否有一种很好的方法从uint64_t[N]构造一个bitset<64 * N> ,使得flags[0]表示最低的64位?

uint64_t flags[3];
// ... some assignments
std::bitset<192> bs{flags};  // this very unhelpfully compiles
                             // yet is totally invalid

Or am I stuck having to call set() in a loop? 还是我不得不循环调用set()

std::bitset has no range constructor, so you will have to loop, but setting every bit individually with std::bitset::set() is underkill. std::bitset没有范围构造函数,因此您必须循环执行,但是用std::bitset::set()单独设置每个位都是徒劳的。 std::bitset has support for binary operators, so you can at least set 64 bits in bulk: std::bitset支持二进制运算符,因此您至少可以批量设置64位:

  std::bitset<192> bs;

  for(int i = 2; i >= 0; --i) {
    bs <<= 64;
    bs |= flags[i];
  }

Update: In the comments, @icando raises the valid concern that bitshifts are O(N) operations for std::bitset s. 更新:在注释中,@ icando引起了人们的关注,即位移是std::bitset的O(N)操作。 For very large bitsets, this will ultimately eat the performance boost of bulk processing. 对于非常大的位集,这最终将吞噬批量处理的性能提升。 In my benchmarks, the break-even point for a std::bitset<N * 64> in comparison to a simple loop that sets the bits individually and does not mutate the input data: 在我的基准测试中, std::bitset<N * 64>的收支平衡点与一个单独设置位并且不改变输入数据的简单循环相比:

int pos = 0;
for(auto f : flags) {
  for(int b = 0; b < 64; ++b) {
    bs.set(pos++, f >> b & 1);
  }
}

is somewhere around N == 200 (gcc 4.9 on x86-64 with libstdc++ and -O2 ). N == 200左右(在x86-64上,带有libstdc ++和-O2 gcc 4.9)中。 Clang performs somewhat worse, breaking even around N == 160 . Clang的性能稍差一些,甚至在N == 160附近收支平衡。 Gcc with -O3 pushes it up to N == 250 . 具有-O3 Gcc将其推升至N == 250

Taking the lower end, this means that if you want to work with bitsets of 10000 bits or larger, this approach may not be for you. 如果使用低端,则意味着如果要使用10000位或更大的位集,则此方法可能不适合您。 On 32-bit platforms (such as common ARMs), the threshold will probably lie lower, so keep that in mind when you work with 5000-bit bitsets on such platforms. 在32位平台(例如常见的ARM)上,阈值可能会更低,因此在此类平台上使用5000位的位集时,请记住这一点。 I would argue, however, that somewhere far before this point, you should have asked yourself if a bitset is really the right choice of container. 但是,我要说的是,在此之前的某个地方,您应该问自己,位集是否真的是容器的正确选择。

If initializing from range is important, you might consider using std::vector 如果从范围初始化很重要,则可以考虑使用std :: vector

It does have constructor from pair of iterators 它确实有一对迭代器的构造函数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM