检查多个位标志 - [PHP] 中的二进制比较

Checking for multiple bitflags - binary comparison in [PHP]

提问人:DevWL 提问时间:4/15/2023 最后编辑:DevWL 更新时间:4/15/2023 访问量:60

问:

检查多个标志。 我只是想知道是否有另一种方法可以检查多个标志,与 &&?

class DemoClass
{

    public const MY_FLAG1 = 0b1;   // 0001 // 1
    public const MY_FLAG2 = 0b10;  // 0010 // 2
    public const MY_FLAG3 = 0b100; // 0100 // 4

    public $flags;

    public function __construct($flags = DemoClass::MY_FLAG1)
    {
        $this->flags = $flags;

        if ($this->flags & DemoClass::MY_FLAG1 && $this->flags & DemoClass::MY_FLAG2) {
            throw new Exception('Flags: MY_FLAG1 and MY_FLAG2 were set');
        }
    }
}

MY_FLAG1 |MY_FLAG2 |MY_FLAG3 = 0b111 // 0111 // 7

传递给构造函数MY_FLAG1的标志 |MY_FLAG2 |MY_FLAG3(0111)。
检查标志是否:MY_FLAG1 |MY_FLAG2设置 (0011)。

例:

new DemoClass(DemoClass::MY_FLAG1 | DemoClass::MY_FLAG2 | DemoClass::MY_FLAG3);
php 比较 bitwise-operators 位标志

评论


答:

4赞 IMSoP 4/15/2023 #1

的结果是一个值,只有当位同时在 和 中时才设置位。$input & $mask$input$mask

如果$mask只设置了一个位,则结果要么全为零,要么设置一个位。这就是您目前正在测试的内容 - 在 if 语句或布尔表达式的上下文中,所有零都等效于 false。

但是想想如果匹配,则设置了哪个位 - 在$mask中设置的位相同,并且只有该位。因此,成功匹配的结果将等于$mask。

如果 $input 和 $mask都设置了多个位,则检查零只能证明$mask中至少有一位也处于$input中。但是,它匹配$mask的唯一方法是,如果$mask中设置的所有位也都设置为$input。

因此,如果你构造一个掩码,并设置了所有你想设置的位,你可以测试($input & $mask) === $mask

在您的示例中:

$mask = DemoClass::MY_FLAG1 | DemoClass::MY_FLAG2;
if (($this->flags & $mask) === $mask) {
   throw new Exception('Flags: MY_FLAG1 and MY_FLAG2 were set');
}

评论

0赞 Michal Hynčica 4/15/2023
我想你把你的例子混淆了。它应该是相等 () 或恒等 () 比较,正如您在示例上方的行中提到的。!=======
0赞 IMSoP 4/15/2023
@MichalHynčica 哦,你是对的,我误读了原始代码,以为它是在说“如果它们没有都设置,那么错误”。已修复,谢谢。