从整数数组构造位集
Posted
技术标签:
【中文标题】从整数数组构造位集【英文标题】:Construct bitset from array of integers 【发布时间】:2015-07-06 06:49:58 【问题描述】:从uint64_t
构造bitset<64>
很容易:
uint64_t flags = ...;
std::bitset<64> bsflags;
但是有没有一种从uint64_t[N]
构造bitset<64 * N>
的好方法,这样flags[0]
将引用最低64 位?
uint64_t flags[3];
// ... some assignments
std::bitset<192> bsflags; // this very unhelpfully compiles
// yet is totally invalid
还是我不得不循环调用set()
?
【问题讨论】:
您的意思是从每个uint64_t
中取出最低8 位吗?以及按什么顺序?
@Wintermute 哎呀。我想要所有的位。 flags[0]
将是最低 64 位。
可能类似于constexpr std::size_t FLAGS_SIZE = 3; uint64_t flags[FLAGS_SIZE]; std::bitset<64 * FLAGS_SIZE>();
?
std::bitset 没有接受元素数组的转换(其中 elements 是底层 std::bitset 类型)。在我看来,这是一个失败,因为 std::vectorstd::bitset
没有范围构造函数,所以你必须循环,但是用std::bitset::set()
单独设置每个位是不够的。 std::bitset
支持二元运算符,所以至少可以批量设置 64 位:
std::bitset<192> bs;
for(int i = 2; i >= 0; --i)
bs <<= 64;
bs |= flags[i];
更新:在 cmets 中,@icando 提出了对std::bitset
s 的位移是 O(N) 操作的有效担忧。对于非常大的位集,这最终会吃掉批量处理的性能提升。在我的基准测试中,std::bitset<N * 64>
的盈亏平衡点与单独设置位且不改变输入数据的简单循环相比:
int pos = 0;
for(auto f : flags)
for(int b = 0; b < 64; ++b)
bs.set(pos++, f >> b & 1);
在N == 200
附近(x86-64 上的 gcc 4.9,带有 libstdc++ 和-O2
)。 Clang 的表现稍差,在N == 160
附近收支平衡。带有 -O3
的 Gcc 将其推高到 N == 250
。
取低端,这意味着如果您想使用 10000 位或更大的位集,这种方法可能不适合您。 在 32 位平台上(例如常见的 ARM) ,阈值可能会更低,因此在此类平台上使用 5000 位位集时请记住这一点。但是,我认为,在此之前的某个地方,您应该问自己 bitset 是否真的是容器的正确选择。
【讨论】:
如果 bs 是 bitsetO(N)
操作,所以整个循环是 O(N^2)
操作。没有人注意到这一点?std::bitset
,那就太好了。但是,对于合理的用例,我不相信会达到阈值。
@Wintermute 酷。我正在处理非常小的N
s,主要对代码清晰度而不是性能感兴趣,所以双赢!另外,
【参考方案2】:
如果从范围初始化很重要,您可以考虑使用 std::vector
它确实有来自一对迭代器的构造函数
【讨论】:
以上是关于从整数数组构造位集的主要内容,如果未能解决你的问题,请参考以下文章