C++快速位集短路按位运算
演示问题:给定两个 std::bitset
,a
和 b
检查两个 中是否设置了任何位a
和 b
。
对于这个问题有两个相当明显的解决方案。这很糟糕,因为它创建了一个新的临时位集,并将值复制到各种位置只是为了将它们丢弃。
template <size_t N>
bool any_both_new_temp(const std::bitset<N>& a, const std::bitset<N>& b)
{
return (a & b).any();
}
这个解决方案很糟糕,因为它一次一位,这不太理想:
template <size_t N>
bool any_both_bit_by_bit(const std::bitset<N>& a, const std::bitset<N>& b)
{
for (size_t i = 0; i < N; ++i)
if (a[i] && b[i])
return true;
return false;
}
理想情况下,我能够做这样的事情,其中 block_type
是 uint32_t
或无论 bitset
存储什么类型:
template <size_t N>
bool any_both_by_block(const std::bitset<N>& a, const std::bitset<N>& b)
{
typedef std::bitset<N>::block_type block_type;
for (size_t i = 0; i < a.block_count(); ++i)
if (a.get_block(i) & b.get_block(i))
return true;
return false;
}
有没有一种简单的方法可以做到这一点?
A demo problem: Given two std::bitset<N>
s, a
and b
check if any bit is set in both a
and b
.
There are two rather obvious solutions to this problem. This is bad because it creates a new temporary bitset, and copies values all sorts of places just to throw them away.
template <size_t N>
bool any_both_new_temp(const std::bitset<N>& a, const std::bitset<N>& b)
{
return (a & b).any();
}
This solution is bad because it goes one bit at a time, which is less than ideal:
template <size_t N>
bool any_both_bit_by_bit(const std::bitset<N>& a, const std::bitset<N>& b)
{
for (size_t i = 0; i < N; ++i)
if (a[i] && b[i])
return true;
return false;
}
Ideally, I would be able to do something like this, where block_type
is uint32_t
or whatever type the bitset
is storing:
template <size_t N>
bool any_both_by_block(const std::bitset<N>& a, const std::bitset<N>& b)
{
typedef std::bitset<N>::block_type block_type;
for (size_t i = 0; i < a.block_count(); ++i)
if (a.get_block(i) & b.get_block(i))
return true;
return false;
}
Is there an easy way to go about doing this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我用
g++
优化编译了您的第一个示例,它生成的代码与您的第三个解决方案相同。事实上,使用较小的位集(320 位)就可以完全展开它。如果没有调用函数来确保a
和b
的内容在main
中是未知的,它实际上优化了整个事情(知道两者都是) 0)。教训:编写明显、可读的代码并让编译器处理它。
I compiled your first example with optimization in
g++
and it produced code identical to your third solution. In fact, with a smallish bitset (320 bits) it fully unrolled it. Without calling a function to ensure that the contents ofa
andb
were unknown inmain
it actually optimized the entire thing away (knowing both were all 0).Lesson: Write the obvious, readable code and let the compiler deal with it.
您说您的第一种方法“复制各种位置的值只是为了将它们丢弃”。但实际上只有一个额外的值复制(当
operator&
的结果返回到any_both_new_temp
时),并且可以通过使用引用而不是值来消除它:(但显然它仍然会创建一个临时
bitset
并将a
复制到其中。)You say that your first approach "copies values all sorts of places just to throw them away." But there's really only one extra value-copy (when the result of
operator&
is returned toany_both_new_temp
), and it can be eliminated by using a reference instead of a value:(But obviously it will still create a temporary
bitset
and copya
into it.)