检查bitset是否包含另一个bitset的所有值

时间:2013-10-08 21:17:27

标签: c++ bit-manipulation bitwise-operators bit bitset

我试图创建一个实体/组件系统,自动匹配合适的实体适合的系统。我使用std::bitsetRTTI自动为每个组件类型分配一个位值。

系统定义如下:MovementSystem : System<Position, Velocity>

在此示例中,

MovementSystem接受同时包含PositionVelocity组件(以及任何其他组件)的任何实体。

为了检查实体是否合适,我将系统的bitset与实体的bitset进行比较。

// Let's assume there are max 4 components

1          1          0         1        // Entity bitset
^          ^                    ^
Position   Velocity             OtherB

1          1          0         0        // Suitable example system bitset
^          ^
Position   Velocity

1          1          1         0        // Unsuitable example system bitset
^          ^          ^                  // Entity does not have OtherA!
Position   Velocity   OtherA

到目前为止,我的解决方案就是这个:

if(entityBitset & systemBitset) == systemBitset)) { /* entity is suitable! */ }

似乎可以工作,但是我在白板上涂抹了bitset后发现了它。这是对的吗?可以进一步改进吗? (实体将在我的游戏中创建和销毁很多次,因此性能非常重要!)


如果需要,代码为here(不应该),但几乎不可能阅读。

1 个答案:

答案 0 :(得分:3)

您的支票

a & b == b;     // check whether b is a subset of a

检查ba的子集,还是等效的,a是否包含/ b。请注意,您要创建一个临时,然后是break-early operator==

这相当于检查ba的差异是否为空(请注意顺序!)

(b & ~a).none(); 

这同样会很快:一个临时的,然后是休息时间.none()

鉴于std::bitset的界面,这是你能得到的速度。 std::bitset的问题在于,所有按位成员(&|^~都会循环遍历每个单词。提前终止操作,例如{{} 1}},none()any()==不能与它们交织在一起。这是因为<没有公开底层字存储,因此您无法自己执行迭代

但是,如果您要编写自己的bitset类,则可以编写一个专用的std::bitset算法,循环遍历每个单词,执行includes()直到您提前中断

&

// test whether this includes other bool YourBitSet::includes(YourBitSet const& other) const { for (auto i = 0; i < NumWords; ++i) if (otherword[i] & ~(this->word[i]) != 0) return false; return true; } 中遗漏的类似算法为std::bitset,以便有效地测试intersects()。目前你必须首先按位进行,然后进行零测试,而这样可以在一个循环中更有效地完成。如果a & b != 0得到更新,那么如果它们包含std::bitsetincludes()原语就会很好。