[PHP]中的二进制比较(binary comparison)

af7jpaap  于 2023-04-19  发布在  PHP
关注(0)|答案(1)|浏览(170)

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

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);
h6my8fg2

h6my8fg21#

$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');
}

相关问题