Bits can be manipulated in multiple ways through the use of bitwise operators. The utilization of operators such as |, &, ,, >>, between bits is analogous to the use of mathematical operators like +, -, /, * between integers.
In this article, we will examine six different categories of bitwise operators in C++. In C++, we will comprehend both their internal workings and their syntax.
- AND (&)
- OR (|)
- XOR (^)
- COMPLEMENT (~)
- Left Shift (<<)
- Right Shift (>>)
Although certain operators may share similarities in names and symbols with logical operators, it is important to note that they serve distinct functions and cannot be used interchangeably.
Bitwise Operators vs Logical Operators in C++:
For newcomers, bitwise operators such as AND, OR, and XOR may pose challenges in comprehension.
Logical AND and Logical OR might be concepts you are acquainted with if you have prior knowledge of logical operators. It is quite common for individuals to confuse them with the Bitwise AND and Bitwise OR operators. Let's delve into understanding the distinctions between them. Unlike Bitwise operators, the logical operators operate on Boolean data types and yield a Boolean result of either True or False.
Bitwise operations in C++ are designed to work specifically with integers. This means that they take integer values as input, perform manipulation at the bit level, and produce an integer result. Unlike logical operators like '&&' and '||', bitwise operators '&' and '|' are used for bitwise AND and OR operations respectively.
Bitwise operator types in C++
Now that you have a clear understanding of the contrast between logical and bitwise operators along with the purpose of bitwise operators, let's delve deeper into each of these operators.
AND (&) Operator:
A lone & symbol is employed to denote the bitwise AND operator. This binary operator necessitates a pair of operands, or two numerical values, to operate.
It performs a bitwise logical AND operation on the binary values of the left and right operands. In other words, when both operands contain a 1 in a specific position, the result will also be 1 in that position; otherwise, it will be 0.
Truth table for Bitwise AND operator in C++:
| Num1 | Num2 | Result=Num1 & Num2 |
|---|---|---|
0 |
0 | 0 |
1 |
0 | 0 |
0 |
1 | 0 |
1 |
1 | 1 |
Example:
#include <iostream>
int main() {
int ans, num1 = 3, num2 = 4;
ans = num1 & num2;
std::cout<< "3 & 4 = " <<ans<< std::endl;
return 0;
}
Output:
3 & 4 = 0
Working Mechanism:
The bitwise AND operation on 3 and 4 is carried out by the snippet of code above. Let's take a closer look at how they operate.
- In binary, 4 equals 100 and 3 is 11
- By adding zeros to the left side of the most significant bit, the shortest binary value must first be converted to the length of the longest binary value.
- Here, 3 has a length of 2 , whereas 4 has a length of 3 , making it the greatest number. Add 0s as the most significant bit in 3 to make them the same length.
- The binary representation for 3 is now 011 , and for 4 it is 100 .
- Now, perform logical AND operations on the bits, going from left to right , and store the outcome in the corresponding location.
- The logical AND will treat 0 as False and 1 as True . Therefore the result will be false , and 0 will be the first bit of the result. The first bit of 3 is 0 , and the first bit of 4 is 1 .
- Over the course of the binary values, the same procedure is repeated. Since the second bits of 3 and 4 are 0 and 0 , the second bit of the result will be saved as 0 .
- Again, 0 will be the third and last bit of our result because the third and last bits of both 3 and 4 are 0 and 0 .
- Therefore, 000 will be the final binary value of our result, which equals 0 when translated to integer decimal.
OR Operator:
The key distinction between the bitwise AND and bitwise OR operators lies in their logical operations at the bit level. The bitwise OR operator executes logical OR instead of logical AND, meaning that if either operand has a value of 1, the result will also be 1 in that position; only when both operands are 0 will the result be 0 in that position. This operation is denoted by the vertical bar or pipe symbol, |.
Truth table for Bitwise OR operator in C++:
| Num1 | Num2 | Result=Num1 | Num2 |
|---|---|---|---|
0 |
0 | 0 | |
1 |
0 | 1 | |
0 |
1 | 1 | |
1 |
1 | 1 |
Example:
#include <iostream>
int main() {
int ans, num1 = 3, num2 = 4;
ans = num1 | num2;
std::cout<< "3 | 4 = " <<ans<< std::endl;
return 0;
}
Output:
3 | 4 = 7
Working Mechanism:
The bitwise OR operation on 3 and 4 is carried out by the piece of code above. Let's take a closer look at how they operate.
- In binary terms, 4 is equal to 100 and 3 is equal to 11 , respectively.
- By adding zeros to the left side of the most significant bit, the shortest binary value must first be converted to the length of the longest binary value .
- Now, we have 011 for 3 and 100 for 4 .
- Now, perform logical OR operations on the bits, going from left to right , and store the outcome in the corresponding location.
- Since the initial bits of 3 and 4 are 0 and 1 , respectively, the result's first bit is 1 .
- Since the second bits of 3 and 4 are both 1 and 0 , the second bit of the outcome is also 1 .
- The third bit of the result is 1 because the third bits of 3 and 4 are both 1 and 0 , respectively.
- Thus, the result's binary value is 111 , which gets 7, when converted to decimal form.
XOR Operator:
The primary difference between this operation and the other two is that it performs a logical XOR operation at the binary level. This means the output will contain a 1 in a specific position only if one operand is 1 and the other is 0. In cases where both operands have identical bits, either both 0s or both 1s, the result will be 0.
Truth table for Bitwise XOR operator in C++:
| Num1 | Num2 | Result=Num1^Num2 |
|---|---|---|
0 |
0 | 0 |
1 |
0 | 1 |
0 |
1 | 1 |
1 |
1 | 0 |
Example:
#include <iostream>
int main() {
int ans, num1 = 3, num2 = 4;
ans = num1 ^ num2;
std::cout<< "3 ^ 4 = " <<ans<< std::endl;
return 0;
}
Output:
3 ^ 4 = 7
Working Mechanism:
The bitwise XOR operation on 3 and 4 is carried out by the snippet of code above. Let's take a closer look at how they operate.
- In binary terms, 4 is equal to 100 and 3 is equal to 11 , respectively.
- We must first extend the shortest binary value to its full length by adding zeros to the most important bit's left side .
- The binary representation for 3 is now 011 , and for 4 it is 100 .
- Now, working from left to right , logically XOR the bits and then store the outcome in the corresponding location.
- Since the initial bits of 3 and 4 are 0 and 1 , respectively, the result's first bit is 1 .
- Since the second bits of 3 and 4 are both 1 and 0 , the second bit of the outcome is also 1 .
- The third bit of the result is 1 because the third bits of 3 and 4 are both 1 and 0 , respectively.
- The result's binary value is 111 , which gives us the number 7 when converted to decimal form.
Before proceeding to explore additional operators, it's beneficial to examine the truth tables for the three bitwise operators in C++ that have been previously discussed.
| X | Y | x& y | X | y | X ^ y |
|---|---|---|---|---|---|
0 |
0 | 0 | 0 | 0 | |
0 |
1 | 0 | 1 | 1 | |
1 |
0 | 0 | 1 | 1 | |
1 |
1 | 1 | 1 | 0 |
Tab :- A common truth table in C++ for the bitwise AND, OR , and XOR operations.
Complement Operator:
If you've noticed, the previous three bitwise operations we've covered were all binary operators, requiring two operands each to operate. Nevertheless, this particular operator is unique as it functions with just a single operand. Unlike other bitwise operations that necessitate two operands, this one stands alone in its requirement for only one operand.
The bitwise complement operator provides the one's complement of a given value. The one's complement of a number is generated by flipping all the 0s to 1s and all the 1s to 0s in its binary representation. This operation is denoted by the tilde symbol, which is '~'.
The truth table for the Bitwise Complement operator in C++ is as follows:
| a | ~a |
|---|---|
0 |
1 |
1 |
0 |
| Num1 | Result = ~Num1 |
|---|---|
0 |
1 |
1 |
0 |
Example:
#include <iostream>
int main() {
int ans, num1 = 5;
ans = ~num1;
std::cout<< "~5 = " <<ans<< std::endl;
return 0;
}
Output:
~5 = -6
Working Mechanism:
The provided code snippet executes the bitwise NOT operation on the number 5. Inverting all the bits yields 101, which translates to 010 or 2 in decimal form.
Note:
- In this case, logic dictates that 5 = 2 , but the compiler instead outputs the input value's complement of 2 .
- Use 2's complement to store negative numbers .
- The binary code for 5 is 0000 0101 .
- 1111 1010 is one's complement of 5.
- The binary code for 6 is 0000 0110.
- The number 1 to 6 is 1111 1001 .
- To get the 2's complement of 1, add 1 to its one's complement ( 6 = 1111 1010 ). It is equal to 5 .
- Hence, 6 is a 5's bitwise complement.
We have discussed 4 bitwise operators within the C++ language up to this point. These operators perform the same operations at the bit level as the logical operators do with boolean variables, resulting in a close resemblance between them. Nonetheless, the following two operators exhibit notable differences from each other.
Left Shift (__PRESERVE_15__>) Operator
The primary contrast between the right shift and left shift operators lies in the direction of the shift operation. The right shift operator moves the bit positions towards the right instead of the left. The conversion of the remaining bits from binary to an integer involves discarding the last n bits from the given value.
The Right Shift operator abides by the same principles as the Left Shift operator. In case the value of "n" is negative, a compiler error indicating "negative shift count" will be raised. It is permissible for the value of "x" to be negative, unlike the value of "n" which must be non-negative.
When utilizing the right shift operator on a negative value, it employs the 2's complement of the number, similar to the mechanism used by the left shift operator.
When performing a right shift operation on a negative integer, the result will turn positive because the sign bit is replaced with 0 after shifting the preceding 1 bit to the adjacent position. This operation is denoted by the double greater-than symbols or >>.
Syntax:
It has the following syntax:
ans = x >> n;
It involves dividing the provided integer by the square of the floor value of n.
When you move a number to the right, similar to shifting it to the left, you are essentially dividing it by the base value. When you perform a right shift and remove the last digit from the number 345 in decimal representation, you are effectively dividing it by 10 at the least significant position, which corresponds to its base value.
For example, shifting 345 to the left by one position results in 34, equivalent to dividing 345 by 10. This principle applies uniformly to all fundamental values. The result remains consistent with dividing by powers of 2, as the Right Shift operator operates on binary numbers.
Example:
#include <iostream>
int main() {
int ans, num1 = 20;
ans = num1 >> 2;
std::cout<< "20 >> 2 = " <<ans;
return 0;
}
Output:
20 >> 2 = 5
Working Mechanism:
- The Right Shift operation is applied to the decimal value 20 in the code snippet above.
- The bit patterns of 20 are moved by 2 .
- 20 has a binary value of 10100 .
- The result is 101 when you pop the final two bits and shift it to the right by two positions.
- When the outcome is transformed from binary to integer , it gets 5.
Conclusion:
In this article, you learned what bitwise operators are, how they differ from logical operators , and what they do in the C++. When utilized correctly, bitwise operations can help you save a tonne of time. Some of the most popular applications for bit manipulation techniques include:
- Lowercase English characters are created by using the OR symbol (|) and the space bar .
- Underlining converts English to uppercase when used with AND ('&') .
- For the case-swapping of English characters , use XOR "" and the space bar .
- Switching two digits.
- Verify if the supplied number has a 2 exponent .