Bitwise operators are one of those concepts that a lot of programmers don’t understand. These are not used a great deal anymore so you can get away with not knowing them but they can still come in handy for a number of different scenarios.

If you end up writing algorithms for encryption and video compression then it is definitely something you need to know.

As you can probably guess from the name, bitwise operators work on the individual bits. If you want to perform operations on binary numbers then you need to use bitwise operators.

Bitwise operations aren’t the most intuitive of things so before I go through the different types of bitwise operators it is worth looking at why we use them.

Bitwise operators were used a lot more in programming when computers didn’t have as much memory in them as they do now. Bitwise operators are still used for those working on embedded devices that have memory limitations.

The smallest amount of space a variable can take up is 1 byte. The reason for this is that it is the smallest unit of addressable space that a CPU can reference.

Even a boolean that only has the values `true`

and `false`

and therefore should only take up 1 bit still uses a full byte and has the remaining 7 bits padded out.

```
0000 0001 = true
0000 0000 = false
```

This isn’t great if you are trying to save memory.

Most applications have multiple flags, especially those that are referencing physical hardware.

To make the most out of the available space programmers would combine multiple flags into a single byte allowing them to store up to 8 different boolean values.

Which is just what you need if you are trying to conserve memory on a small device.

The one place you might have seen multiple flags being stored is with unix file permissions. Typically you might see file permissions denoted as numbers like `644`

or `777`

.

The first number is the permissions for the file owner, the second is the permissions for the group and the third is for everyone else.

The number tells you whether they have permission to read a file, write to a file or execute a file.

To understand what each number means you need to convert the number into binary first.

`7`

in binary is `111`

which means they have the ability to read, write and execute.
`6`

in binary is `110`

which means they have the ability to read and write but not execute.
`4`

in binary is `100`

so they only have permission to read the file.

Now we have an example in mind let’s have a look at what the bitwise operators are.

There are 6 bitwise operators and each has a different purpose.

In most programming languages we use a single ampersand (&) for the AND operator.

The best way to describe how the operators work is to use truth tables.

Using the AND operator with 2 numbers will leave you with the bits that match each number.

For example, if we take 7 and 6:

```
7 & 6 = 6
---------
1 1 = 1
1 1 = 1
1 0 = 0
```

Here we can see that the first 2 rows have a matching bit but the last one doesn’t so the final result is `110`

or `6`

as a decimal.

Going back to our file permissions example. The AND operator can be used to test whether the user has permission to access something.

As the AND operator will give you only the bits back that match you can test to see if your user has those permissions.

```
READ_PERMISSION = 4
WRITE_PERMISSION = 2
EXECUTE_PERMISSION = 1
userPermissions = 6
if (userPermissions & READ_PERMISSION) == READ_PERMISSION:
print("Can Read")
else:
print("Cannot Read")
print(userPermissions & READ_PERMISSION)
```

Output:

```
Can Read
4
0b100
```

The OR operator compares each bit and will give you the result if either one or the other is set to 1.

If we look at 5 and 6 using the OR operator and compare each bit we can see at least one of the rows the bit is set. The final result is therefore going to be 111 in binary or 7 in decimal.

```
5 | 6 = 7
---------
1 1 = 1
0 1 = 1
1 0 = 1
```

You can use the OR operator to combine multiple flags together into a final result.

Here we put together the read-and-write permission using the OR operator and the final result we can see is 6.

```
READ_PERMISSION = 4
WRITE_PERMISSION = 2
EXECUTE_PERMISSION = 1
userPermissions = READ_PERMISSION | WRITE_PERMISSION
print(userPermissions)
print(bin(userPermissions))
```

Output:

```
6
0b110
```

You can even use the OR operator when assigning a value to an existing value.

Say we want to give the user the execute permission again we can add that using the OR assignment operator

```
READ_PERMISSION = 4
WRITE_PERMISSION = 2
EXECUTE_PERMISSION = 1
userPermissions = READ_PERMISSION | WRITE_PERMISSION
userPermissions |= EXECUTE_PERMISSION
print(userPermissions)
print(bin(userPermissions))
```

Output:

```
7
0b111
```

This operator requires each bit to be the opposite of the other. When one is zero the other one has to be one.

If we look at the values 5 and 6 again. For the first bit, they both have the value 1 and therefore the exclusive or will return zero. The last 2 bits are both opposites and so that will return one. The final result is 011 which is 3 in decimal.

```
5 ^ 6 = 3
---------
1 1 = 0
0 1 = 1
1 0 = 1
```

If we go back to our permissions example you can use the exclusive or remove permissions from the existing permission set.

Here we have a user who has the permissions to read and write. With the exclusive or assignment, we can remove the write permission from the user.

```
READ_PERMISSION = 4
WRITE_PERMISSION = 2
EXECUTE_PERMISSION = 1
userPermissions = READ_PERMISSION | WRITE_PERMISSION
userPermissions ^= WRITE_PERMISSION
print(userPermissions)
print(bin(userPermissions))
```

Output:

```
4
0b100
```

The NOT operator `~`

will give you the opposite value for each of the bits in your number.

Unlike the other operators, it doesn’t work on two values but just flips the value of each of the bits in the number.

```
~5
1 = 0
0 = 1
1 = 0
```

If you do this example in python with a number you are going to get a negative number which might be a bit surprising at first.

As I mentioned in my last video on binary numbers the first bit of a number denotes the sign of the number with 0 being positive and 1 being negative.

When you use the NOT operator it flips all the bits in the number so the first bit becomes 1, therefore, making it negative.

As Python uses an 8-bit number to represent small numbers, 5 would be written like this.

`0000 0101`

When this is reversed it becomes:

`1111 1010`

Binary numbers use something called the two’s complement representation. All you need to understand is that in this case, an 8-bit negative number will start from `-128`

.

We can then add each bit to this which gives us the final result of `-6`

.

`-128 + 2^6 + 2^5 + 2^4 + 2^3 + 2^1`

As the name suggests these operators shift all of the bits either to the left or to the right.

Again like the NOT operator this only works on a single number and the second number denotes the number of bits to shift by

The number 5 in a 8-bit binary is `0000 0101`

:

If we use the left shift operator with a 2, all of the bits are going to be shifted two bits to the left.

```
number = 5
print(number)
print(bin(number))
number = number << 2
print(number)
print(bin(number))
```

Output:

```
5
0b101
20
0b10100
```

The 2 leftmost bits are going to be discarded, although these are 0 in our case anyway. The other bits are going to shift left by 2. So this then becomes

`0001 0100`

If we convert it to decimal is going to give us 20.

If we then take this number and shift it right by 2 bits then it is going to become 5 again.

```
number = 5
print(number)
print(bin(number))
number = number << 2
print(number)
print(bin(number))
number = number >> 2
print(number)
print(bin(number))
```

Output:

```
5
0b101
20
0b10100
5
0b101
```

And that’s all there is to it. Bitwise operators can seem confusing at first but once you get used to thinking in binary they aren’t too scary.

📨 My free weekly newsletter, **The Curious Engineer**, is written for engineers like you, packed with advice and essential knowledge that you need to grow in your career.

📨 Preview my weekly newsletter🙏 **Was this helpful?** If you want to say thanks, I love coffee ☕️ , any support is appreciated.

People love to joke about recursion. As the saying goes: “In order to understand recursion, one must first understand recursion.” You will…

Working with arrays can be a bit of a pain in most languages. If you want to make changes to an array you need to use a FOR loop, a bit like…

There’s nothing like a regular expression to strike fear in the heart of a developer. Regular expressions (regex) are used for a lot of…

When I was 8 years old I learnt how to code. I learnt to code from an old BASIC book that my Dad had lying around from his ZX Spectrum. I…

It’s important when you’re writing applications especially, those that are going to be processing a large amount of data that you understand…

In modern programming languages such as C# or Java, we tend to take memory management for granted. Gone are the days when we need to call…

Losing code that you have spent hours writing can be painful, which is why we use version control (or source control) to store our code and…

You can get pretty far in programming without understanding Data Structures, but eventually, you are going to need to know them, understand…