# Understanding Bitwise Operators with PHP

## One of the unknown features in PHP is Bitwise Operators. In the article, we will learn things through practice with a real example!

Bit operations are rare in the PHP world, however, in books, articles, or other sources, you might find something like:

```
$memory = memory_get_usage() >> 20;
```

You may get confused. What is "`>>`

"? So, let's look at the documentation .

`$a >> $b`

Shift the bits of`$a $b`

steps to the right (each step means "divide by two")

# WTF?! Why do you need it at all? So let's dive into it.

Many people know that binary (or base-2) a numeric system that only uses two digits — `0`

and `1`

. Computers operate in binary, meaning they store data and perform calculations using only zeros and ones. So, for example, a computer will represent the number `6`

as `00000110`

.

Bit Rotation : A rotation (or circular shift) is an arithmetic operation.

- In the left rotation, the bits that fall off at the left end are put back at the right end.
- In the right rotation, the bits that fall off at the right end are put back at the left end.

# Let's back to our operator "`>>`

".

```
$n = 6; // 00000110
$k = $n >> 1; // 00000011
```

We can see that the bits that fall off at the right end are put back at the left end. So the current binary value `00000011`

in decimal is `3`

. We just shifted one bit, and as a result, we divided the value by `2`

.

If we were to shift `2`

bits, we would divide by `4`

.

If we were to shift `3`

bits, we would divide by `8`

.

# Wow, that's the power of two!

Get back to the example `>> 20`

. It means that we are dividing the value by `2`

to the power of 20.
It is easy to remember that `2 ^ 10 = 1024`

. So

```
$memory = memory_get_usage() / (1024 * 1024);
```

Since `memory_get_usage()`

returns a value in bits, we just converted it to megabytes. It turns into a very handy function:

```
$memory = memory_get_usage() >> 10; // convert it to kilobytes (KB)
$memory = memory_get_usage() >> 20; // convert it to megabytes (MB)
$memory = memory_get_usage() >> 30; // convert it to gigabytes (GB)
$memory = memory_get_usage() >> 40; // convert it to terabyte (TB)
```

If right rotation means division, then left rotation, on the contrary, means multiplication.

```
$y = 5; // 000000101
echo $y << 2; // 000010100 (5 * 4 = 20)
```

## Are there other operators besides right/left rotation?

There are 4 more operations - `AND &`

, `OR |`

, `XOR ^`

, `NOT ~`

. Let's see it in action below.

# What's the best way to use bitwise operations?

The most convenient to use bitwise operations, not in multiplication and division, but is using a bitwise mask, for example, to differentiate access rights or other similar things.

We can turn four values into a four-bit value, in which `1`

means the user has the given right, and `0`

does not.

```
define('U_READ', 1 << 0); // 0001
define('U_CREATE', 1 << 1); // 0010
define('U_EDIT', 1 << 2); // 0100
define('U_DELETE', 1 << 3); // 1000
define('U_ALL', U_READ | U_CREATE | U_EDIT | U_DELETE); // 1111
```

In the first `four lines`

, we defined the constants by shifting bits to the left. After that, we used the `OR |`

operator on the last line. The bitwise OR operator (|) returns a `1`

in each bit position for which the corresponding bits of either or both operands are `1s`

. Example:

```
$x = 3; // 0011
$y = 5; // 0101
echo $x | $y; // 0111 (7)
```

Therefore, we can set any permissions for the user:

```
$userPermission = U_READ; // Only read
$userPermission = U_READ | U_CREATE; // Only read and create
$userPermission = U_ALL ^ U_DELETE; // All rights except deletion
$userPermission = U_ALL & ~ U_DELETE; // Again all rights except deletion
```

In the example above, there are `3`

new operators.

- A bitwise XOR operator (^) (performs the logical exclusive OR). It returns a
`1`

in each bit position for which the corresponding bits of either but not both operands are`1s`

. - The bitwise AND operator (&) returns a
`1`

in each bit position for which the corresponding bits of both operands are`1s`

. - The bitwise NOT operator (~) inverts the bits of its operand.

Example:

```
#XOR
$x = U_ALL; // 1111
$y = U_DELETE; // 1000
echo $x ^ $y; // 0111
#AND
$x = U_ALL; // 1111
$y = U_DELETE; // 1000
echo $x & $y; // 1000
#NOT
$y = U_DELETE | U_READ; // 1001
echo ~$y; // 0110 (inverted)
```

### What happens if we use `AND`

+ `NOT`

operators?

In the example below, use the two operators together. The `bitwise NOT operator (~)`

will be executed first, followed by the `bitwise AND operator (&)`

.

```
...
$userPermission = U_ALL & ~ U_DELETE; // Again all rights except deletion
U_ALL 1111
~ U_DELETE 0111
RESULT 0111
```

### Is there any difference between the `XOR`

and `AND`

+ `NOT`

operators?

The difference between these options is that in the first case, the bit switches. If it was `1`

, then it will become `0`

, and vice versa. The second option makes the bit equal to `0`

, regardless of its current value.

If we want to remove any access right, do the following:

```
$userPermission &= ~ U_DELETE; // prohibit deletion
```

### A few more examples:

To check the bits (in our case, the access rights), we can use the following conditions.

```
if ($userPermission & U_READ) // is there a right to read?
if ($userPermission & (U_READ | U_DELETE)) // is there a right to read or/and delete?
```

One more example:

```
// A lot of code duplication
if ($error['type'] == E_ERROR
|| $error['type'] == E_PARSE
|| $error['type'] == E_COMPILE_ERROR) {}
//Better
if (in_array($error['type'], [E_ERROR, E_PARSE, E_COMPILE_ERROR])) {}
//Perfect)
if ($error['type'] & (E_ERROR | E_PARSE | E_COMPILE_ERROR)) {}
```

Although error codes in PHP are specially designed for bitwise operations, developers usually use comparison operators. But now you know a different approach 😉

# Conclution

Thanks for reading this article! I hope you now understand bitwise operators and can utilize them in your PHP code (or in many other languages!). if you have any questions or comments, please leave them below. I appreciate any feedback!

Stay tuned for new articles by following me on Twitter or LinkedIn! Subscribe to my newsletter or RSS. Drop me an email if you have any questions.