代码之家  ›  专栏  ›  技术社区  ›  CinCout robowen5mac

如何检查位枚举中是否存在值?

  •  1
  • CinCout robowen5mac  · 技术社区  · 6 年前

    我有一个 enum

    enum Rule
    {
        BIT_NONE,
        BIT_ONE,
        BIT_TWO = 1 << 1,
        BIT_THREE = 1 << 2,
        BIT_FOUR = 1 << 3
    };
    

    现在,我如何验证一个特定的 int ? 注意,这个想法也允许 BIT_TWO , BIT_THREE ,和 BIT_FOUR ,因此有效值为 {0, 1, 2, 4, 6, 8, 10, 12, 14}

    如果我查一下 BIT_NONE <= val && val <= BIT_FOUR ,它将不允许上述组合,但也将包括不需要的组合 {3, 5, 7}

    我怎样才能做到这一点?

    2 回复  |  直到 6 年前
        1
  •  2
  •   llllllllll    6 年前

    这需要一些位操作技巧:

    允许所有 enum 作为一个单一的位,你需要确保它小于 BIT_FOUR !((val-1)&val)

    bool is_allowed_single(unsigned val) {
        return BIT_NONE <= val && val <= BIT_FOUR && !((val-1)&val);
    }
    

    bool is_allowed_combination(unsigned val) {
        return !(val & ~(BIT_TWO|BIT_THREE|BIT_FOUR));
    }
    

    最后,我们得到:

    bool is_allowed(unsigned val) {
        return is_allowed_single(val) || is_allowed_combination(val);
    }
    
        2
  •  0
  •   user555045    6 年前

    因为枚举很小,所以还有另一种方法:使用所有有效值的预定义掩码。 那个面具是 1 << {0, 1, 2, 4, 6, 8, 10, 12, 14} ,所以 0x5557

    然后检查是否设置了该值对应的位:

    bool is_allowed(unsigned val) {
        return (0x5557 & (1 << val)) != 0;
    }
    

    这有一个先决条件,即值不会超出集合的范围,但如果期望值存在,则可以通过比较轻松检查它们。