何时应使用按位运算符?

我阅读了以下堆栈溢出问题,并了解按位和逻辑之间的差异。

但是,它们都没有解释我何时应该按位或逻辑使用。

我什么时候应该使用按位运算符而不是逻辑运算符,反之亦然?

在哪种情况下,我需要逐点比较?

我不是在问差异,而是在问什么时候需要使用按位运算符的情况。


答案 1

Bitwise对于PHP中的东西很有用,就像其他任何东西一样。

可以同时打开多个状态的值怎么样?

<?php

// since we're setting constant values in base10 we must progressively double
// them since bitwise operations work in base2. you'll see why when we output
// these as binary values below.
const STATE_FOO = 1;
const STATE_BAR = 2;
const STATE_FEZ = 4;
const STATE_BAZ = 8;

// show base2 values of the above constants
echo sprintf("STATE_FOO's base2 value is %08d\n", decbin(STATE_FOO));
echo sprintf("STATE_BAR's base2 value is %08d\n", decbin(STATE_BAR));
echo sprintf("STATE_FEZ's base2 value is %08d\n", decbin(STATE_FEZ));
echo sprintf("STATE_BAZ's base2 value is %08d\n\n", decbin(STATE_BAZ));

// set state to FOO and FEZ
$state = STATE_FOO | STATE_FEZ;

echo sprintf("base10 value of \$state is %s\n", $state);
echo sprintf("base2 value of \$state is %08d\n", decbin($state));
echo sprintf("Does \$state include FOO state? %s\n", (bool)($state & STATE_FOO));
echo sprintf("Does \$state include BAR state? %s\n", (bool)($state & STATE_BAR));
echo sprintf("Does \$state include FEZ state? %s\n", (bool)($state & STATE_FEZ));
echo sprintf("Does \$state include BAZ state? %s\n", (bool)($state & STATE_BAZ));
echo sprintf("Is state equivalent to FOO and FEZ states? %s\n", ($state == (STATE_FOO | STATE_FEZ)));

输出:

STATE_FOO's base2 value is 00000001
STATE_BAR's base2 value is 00000010
STATE_FEZ's base2 value is 00000100
STATE_BAZ's base2 value is 00001000

base10 value of $state is 5
base2 value of $state is 00000101
Does $state include FOO state? 1
Does $state include BAR state?
Does $state include FEZ state? 1
Does $state include BAZ state?
Is state equivalent to FOO and FEZ states? 1

答案 2

忘记你脑海中已经存在的东西。

好了,现在假设您有一些不同的角色:管理员用户来宾

和一些不同的权限:读取写入删除

让我们为权限角色创建一些位掩码。位掩码是可用于操作或读取某种标志的位序列。如下图所示:

// flags                                bitmasks
$read = 1;                              // 0001
$write = 2;                             // 0010
$delete = 4;                            // 0100

$admin = $read | $write | $delete;      // 0001 | 0010 | 0100 => 0111
$user = $read | $write;                 // 0001 | 0010 => 0011 
$guest = $read;                         // 0001 => 0001

通知 1、2、4。这必须提高为双精度。否则,它可能会给你一些尴尬的结果。

忘记评论的内容。这些只是单个权限和角色的位序列(或位掩码)。

现在,让我们创建一个方便的函数,可用于检查特定角色的特定权限。

function isAllowed($role, $permissison) {
    return $role & $permissison ? true : false;
}

我们完成了。让我们检查所有 3 个角色的$delete权限:

var_dump(isAllowed($admin, $delete));  // bool(true)
var_dump(isAllowed($user, $delete));   // bool(false)
var_dump(isAllowed($guest, $delete));  // bool(false)

那么为什么是按位操作呢?总之,按位操作更快,更简洁,更易于维护。否则,对于复杂的应用程序,使用按位运算始终是有效的。


推荐