In the world of computer logic and digital computing, a single bit can contain 2 possible values which is mostly represented as "0" or "1". The bit is said to be set if its value is  1, and it is unset if the value is 0.

In general terms, masking means hiding/showing something. Likewise, bit masking is a way of hiding/showing certain bits so that the output contains a specific value.

## Bitwise Operators

Bitmasking can be better understood once we are familiar with various bitwise operators. Some bitwise operators are described below.

### AND (&) Operator

The AND operator will return 1 if both values are 1. The truth table for the AND operator is given below:

Let's look at an example of an AND operation.

In the output, we can see that a bit is set only when all bits are 1.

### OR (|) Operator

The OR operator will return 0 if both values are 0. The truth table for the OR operator is given below:

Let's look at an example of an OR operation.

In the output, we see that bit is unset only when all bits are 0.

### NOT (!) Operator

The NOT operator is used to completely flip all the bits. This means that all 0's turn into 1's, and all 1's turn into 0's.

For example, using the NOT operator, `!11100` gives us `00011`.

The truth table for the NOT operator is shown below.

### XOR (^) Operator

The XOR operator works like OR Operator, with the only difference being that the XOR operator returns a 0 when it comes across two 1s, i.e. `1 ^ 1` returns `0` while `1^0` returns `1`.

Let's look at an example of an XOR operation.

In the output, we can see that the bit is flipped whenever there are two 1s.

### Left Shift (<<) Operator

The Left Shift Operator works by shifting the digits towards the left direction of a binary digit, n numbers of time. New bits are left unset, and overflowing bits are erased.

For example,
`00100111<<2`  returns `10011100`,
and `01101010<<1`  returns `11010100`.

### Right Shift (>>) Operator

The Right Shift Operator works by shifting the digits towards the right direction of a binary digit, n numbers of time. Like Left Shift, new bits are left unset, and overflowing bits are erased.

For example,
`00100111>>2`  returns `00001001`,
and `01101010>>1`  returns `00110101`.

When bitmasking is used with various bit operators, it can help solve many problems easily.

### Example

For example, let's say that there is a value (`01000100`) and we want to test if the 4th bit is 1. We first create a mask (`1000`) and use AND operator with our value.

🤔
Why AND? Because AND will return 1 if both values are 1, and by comparing the value to 1000, AND will return 1 if there is a 1 in the 1000th place of the value.

If we perform an operation with our mask and our example value, we get a 0, showing that the 4th bit is not 1. The operation is shown below.

The output is 0, so we test our original value to check if 4th place is 0, and it indeed is 0.

In our implementation, we randomly brought a mask (`1000`). Where did it come from? Well, it is generated by Left Shifting 1 with 3 (`1<<3`). Whenever we want to check the nth place bit, we create a mask by using the formula (`1<<(k-1)`) where k is the nth bit.

So, in our example, we needed to check the 4th bit, which can be calculated as (`1<<(4-1)`), which gives us (`1<<3`), returning (`1000`) – which is the same mask we used in our example.

### More Use Cases of Masking

Masking can also be used when we want to set or flip specific bits. We might need to use multiple operators in succession sometimes to get a specific result.

For example. If we want to set a specific bit to zero, we need to perform various operations in succession. An example of setting the 3rd bit to `0` in value (`11001111`) is shown below.

1. First, create a mask for 3rd bit. This can be done by using the formula (`1<<(k-1)`). Our result becomes (`1 <<(3-1)`), which gives us `00000100`.
2. Now, flip the original digit. `!11001111` becomes `00110000`.
3. Use the OR operation with the flipped value and mask. `00110000|00000100` gives us the `00110100`.
4. Finally, flip the new value to get our final result. `!00110100` now becomes `11001011`.

Like this, we can use various bit operators and masking to manipulate bits.

That's it, I hope you now have a basic understanding of how bitmasking works. I will see you in the next article.