   Bitwise Operators: And, Or, Xor, Left shift, Right shift, Complement: examples and exercises

If you're new to programming, you may be unfamiliar with the concept of bitwise operators. These operators are used to manipulate individual bits in binary numbers. In this article, we'll explore the six different bitwise operators: AND, OR, XOR, left shift, right shift, and complement.

## The AND Operator

The AND operator is represented by a single ampersand (&) and returns 1 if both bits in the operands are 1, and 0 otherwise. For example:

``2 & 3``

This evaluates to 2 because 2 in binary is `10` and 3 in binary is `11`. When we apply the AND operator, we get `10`, which is 2 in decimal.

## The OR Operator

The OR operator is represented by a single pipe symbol (|) and returns 1 if either of the bits in the operands are 1, and 0 otherwise. For example:

``2 | 3``

This evaluates to 3 because 2 in binary is `10` and 3 in binary is `11`. When we apply the OR operator, we get `11`, which is 3 in decimal.

## The XOR Operator

The XOR operator is represented by a caret symbol (^) and returns 1 if the bits in the operands are different, and 0 otherwise. For example:

``2 ^ 3``

This evaluates to 1 because 2 in binary is `10` and 3 in binary is `11`. When we apply the XOR operator, we get `01`, which is 1 in decimal.

## The Left Shift Operator

The left shift operator is represented by two less than symbols (<<) and shifts all the bits in the left operand to the left by the number of positions specified in the right operand. For example:

``2 << 1``

This evaluates to 4 because 2 in binary is `10` and when we shift all the bits to the left by one position, we get `100`, which is 4 in decimal.

## The Right Shift Operator

The right shift operator is represented by two greater than symbols (>>) and shifts all the bits in the left operand to the right by the number of positions specified in the right operand. For example:

``8 >> 1``

This evaluates to 4 because 8 in binary is `1000` and when we shift all the bits to the right by one position, we get `100`, which is 4 in decimal.

## The Complement Operator

The complement operator is represented by a tilde symbol (~) and flips all the bits in the operand. For example:

``~2``

This evaluates to -3 because 2 in binary is `10` and when we flip all the bits, we get `01`, which is `-3` in two's complement notation.

## Examples and Exercises

Now that you understand the different bitwise operators, let's look at some examples and exercises to practice what you've learned.

### Example 1: Set Bit

Suppose you have a number `n` and you want to set the `i-th` bit to 1. You can use the OR operator and left shift operator like this:

``````n = 8
i = 2

# Set 2nd bit
n |= 1 << i

print(n) # Output: 12``````

In binary, `8` is `1000`. We want to set the 2nd bit, so we left shift `1` by `2` positions to get `0100`. Then we use the OR operator to set the 2nd bit to `1`, resulting in `1100` which is `12` in decimal.

### Example 2: Swap Variables

Suppose you have two variables `a` and `b`, and you want to swap their values without using a temporary variable. You can use the XOR operator like this:

``````a = 5
b = 7

# Swap variables
a ^= b
b ^= a
a ^= b

print(a, b) # Output: 7 5``````

In binary, `5` is `0101` and `7` is `0111`. When we perform the first XOR operation (`a ^= b`), we get `0010` for `a` and `0111` for `b`. Then we perform the second XOR operation (`b ^= a`) and get `0010` for `b`. Finally, we perform the third XOR operation (`a ^= b`) and get `0111` for `a`.

### Exercise 1: Count Set Bits

Write a function that takes an integer as input and returns the number of set bits (bits with value 1) in its binary representation.

``````def count_set_bits(n):
count = 0
while n:
count += n & 1
n >>= 1
return count

print(count_set_bits(7)) # Output: 3``````

In binary, `7` is `111`. We loop through each bit of the number by ANDing it with `1` and adding the result to the count if it's a set bit. Then we shift the number to the right by one position to check the next bit.

### Exercise 2: Two's Complement

Write a function that takes an integer as input and returns its two's complement representation.

``````def twos_complement(n):
bits = bin(n & int("1"*32, 2))[2:]
if n < 0:
bits = bits.replace('0', '2').replace('1', '0').replace('2', '1')
return bits.zfill(32)

print(twos_complement(-5)) # Output: 11111111111111111111111111111011``````

In two's complement notation, negative numbers are represented by flipping all the bits in the positive number and adding 1. We first convert the number to binary using the `bin` function. If the number is negative, we flip all the bits using string replacement, and then pad the resulting string with leading zeroes to ensure it has 32 bits.

## Conclusion

Bitwise operators are powerful tools for manipulating individual bits in binary numbers. In this article, we covered the six different bitwise operators: AND, OR, XOR, left shift, right shift, and complement, as well as some examples and exercises to practice what you've learned.

By mastering these operators, you'll be able to write more efficient and concise code, especially in areas like cryptography, networking, and embedded systems. So keep practicing and exploring the world of bitwise operations! Top Tutorials