When should I use a bitwise operator?

2020-01-30 06:36发布

I read the following Stack Overflow questions, and I understand the differences between bitwise and logical.

However, none of them explains when I should use bitwise or logical.

When should I use bitwise operators rather than logical ones and vice versa?

In which situation do I need to compare bit by bit?

I am not asking about the differences, but I am asking the situation when you need to use bitwise operators.

9条回答
聊天终结者
2楼-- · 2020-01-30 06:53

Forget what is already in your head.

OK, now say you have some different roles: admin, user, and guest.

and some different permissions: read, write and delete

Let's create some bitmasks for permissions and roles. A bitmask is a sequence of bits that can be used to manipulate or read some kind of flags. As shown below:

// 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

Notice 1, 2, 4. This must be raised as double. Otherwise, it might give you some awkward results.

Forget about the things commented. Those are just sequence of bits (or bitmasks) for individual permissions and roles.

Now let's create a handy function which may be used to check a specific permission for a specific role.

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

We are done. Let's check the $delete permission for all 3 roles:

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

So why is bitwise operation? In a word, bitwise operation is more faster, concise and maintainable. Otherwise, using bitwise operation is always efficient for complex applications.

查看更多
Fickle 薄情
3楼-- · 2020-01-30 07:02

Well, asuming there is $x = (false && some_function());, here the value of $x will be set without calling the some_function() because the first value was FALSE.

But what if you needed to call that function anyway? Use $x = (false & some_function());.

In other words, the & uses MORE processing than the &&, just because && does not run through all the values to check them. If it found one value as false, it would return it, not looking at other values.

And in logical operations, use the && operator as it's used to return the logical operation value, where & is used to set a value and in an if statement it will always return true.

查看更多
走好不送
4楼-- · 2020-01-30 07:04

Bitwise | and & and logical || and && are totally different.

Bitwise operators perform operations on the bits of two numbers and return the result. That means it's not a yes or no thing. If they're being used in conditional statements, they're often used as part of logical comparisons. For example:

if ($x & 2 == 2) {
    // The 2^1 bit is set in the number $x
}

Logical operators compare two (or more) conditions/expressions and return true or false. You use them most commonly in conditional statements, like if and while. For example:

if ($either_this || $or_this) {
    // Either expression was true
}
查看更多
smile是对你的礼貌
5楼-- · 2020-01-30 07:08

Bitwise is useful for things in PHP just like anything else.

How about a value that can have multiple states turned on at the same time?

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

Output:

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
查看更多
地球回转人心会变
6楼-- · 2020-01-30 07:11

If you want to know more how it works check out this site:

http://www.bitwiseoperatorcalculator.com/

Coming from PHP, I have never used it before but just reading for fun this site gives simple explanations!

查看更多
对你真心纯属浪费
7楼-- · 2020-01-30 07:12

Bitwise operators are specifically used in case of binary value representation.

echo '0110011010' & '0101001001'; 
//0100001000

Logical operators are most preferred for comparison and are a bit faster than bitwise operator in case of AND and XOR operations.

if(func1() && func2())

if func1() returns false it won't bother calling func2()

if(func1() & func2())

Will call both functions regardless of their returned values.

查看更多
登录 后发表回答