Bit Shift Operator in C++
- Left Bit Shift Operator in C++
- Right Bit Shift Operator in C++
- Bit Shift on Float Data Type in C++
- Bit Shift in Array in C++
- Bit Shift and Mask in C++
- Bit Shift for Negative Numbers in C++
- Bit Shift Using Long in C++
- Conclusion
In C++, bit shift operators do what their names suggest, shifting bits. According to the program’s requirements, a bitwise shift operator shifts the binary bits left or right.
Integer values are applied to these operators (int, long, possibly short, and byte or char). In some languages, using the shift operators on any data type smaller than int automatically resizes the operand to be an int.
This article will discuss the Left and Right Shift Operators in C++ and their implementation in detail, along with relevant examples.
Left Bit Shift Operator in C++
The left shift operator shifts the bits in shift expression to the left by the number of places in additive expression. The bit positions vacated by the shift operation are filled with zeros, and the bits shifted off the end are discarded, including the sign bit.
The left shift operator takes two numbers. This shifts the bits of the first operand, and the second operand decides the number of places to shift.
You can say that left shifting an integer a
with an integer b
, denoted by (a<<b)
, is equivalent to multiplying a
with 2^b
(2 raised to power b). The left shift operator is denoted by <<
.
For example, M<<k
. Here, M
is the first operand, and k is the second operand.
Let’s take M=33;
which is 100001 in binary and k = 2
. If M
is left-shifted by 2, denoted by M=M<<2
, it will become M=M(2^2)
.
Thus, M=33(2^2)=132
can be written as 10000100.
Example:
#include <iostream>
using namespace std;
int main() {
unsigned char x = 6, y = 7;
cout << "x<<1 = " << (x << 1) << endl;
cout << "y<<1 = " << (y << 1) << endl;
return 0;
}
Output:
x<<1 = 12
y<<1 = 14
In the above code, the unsigned char x
and char y
variables denote a character datatype in which the variable uses all of the memory’s 8 bits, and there is no sign bit (which is there in signed char).
Here, char x
is equal to 6, i.e., 00000110 in binary, and char y
is equal to 7, i.e., 00000111 in binary.
The first print statement states to left-shift the value of x
by 1 bit; the result is 00001100. The second print statement says to left-shift the value of y
by 1 bit; the result is 00001110.
Right Bit Shift Operator in C++
The right shift operator shifts the bit pattern in shift expression by the number of places additive expression provides to the right. The bit locations vacated by the shift operation are zero-filled for unsigned values.
The sign bit replaces the vacant bit locations in signed numbers. If the number is positive, the value 0 is used; if the number is negative, the value 1 is used.
The right shift operator takes two numbers. This shifts the bits of the first operand, and the second operand decides the number of places to shift.
You can say that right shifting an integer a
with an integer b
, denoted as (a>>b)
, is equivalent to dividing a
with 2^b
(2 raised to power b). The right shift operator is denoted as: >>
.
For example, M>>k
. Here, M
is the first operand and k
is the second.
Let’s take M=32;
which is 100000 in binary and k = 2
. If M
is right-shifted by 2, denoted by M=M>>2
, then M
will become M=M/(2^2)
. Thus, M=32/(2^2)=8
can be written as 1000.
Example program:
#include <iostream>
int main() {
unsigned char x = 6, y = 9;
cout << "a>>1 = " << (a >> 1) << endl;
cout << "b>>1 = " << (b >> 1) << endl;
return 0;
}
Output:
x>>1 = 3
y>>1 = 4
In the above code, the unsigned char x
and char y
variable denotes a character data type in the variable that uses all of the memory’s 8 bits, and there is no sign bit (which is there in signed char).
Here, char x
is equal to 6, i.e., 00000110 in binary, and char y
is equal to 9, i.e., 00001001 in binary.
The first print statement states to right-shift the value of x
by 1 bit; the result is 00000011. The second print statement states to right-shift the value of y
by 1 bit; the result is 00000100.
Bit Shift on Float Data Type in C++
You cannot bit-shift a float in C++ as it will display an error, but why is that? It is because floats are stored in a special format.
32 bits for a float are divided into two categories: a significand and an exponent. A shift can potentially shift bits from the exponent category into the significand category or vice versa.
Example:
#include <stdio.h>
int main(int ar, char *arg[]) {
float testFl = 2.5;
printf("testFloat (before): %f\n", testFl);
testFl = testFl << 1;
printf("testFloat (after): %f\n", testFl);
return 0;
}
Output:
error: invalid operands to binary << (have 'float' and 'int')
The right shift or left shift would collapse all the bits.
Bit Shift in Array in C++
There is an array ar[]
of size n and an integer m
.
The goal is to make all array elements > m
by performing right shift operations on all the array elements present. If you’re not able to do so, then print -1.
Example:
Input: ar[] = { 21, 22, 23, 19 }, m = 34
Output: { 26, 26, 27, 25 }
Explanation:
ar[0] = 10101
After 1 right shift, 11010 → 26
ar[1] = 10110
After 3 right shift, 11010 → 26
ar[2] = 10111
After 1 right shift, 11011 → 27
ar[3] = 10011
After 2 right shift, 11001 → 25
Code:
#include <bits/stdc++.h>
using namespace std;
int setBitNumber(int n) {
int m = log2(n);
return m;
}
bool check(int ar[], int m, int n) {
for (int i = 0; i < n; i++) {
if (ar[i] <= m) return false;
}
return true;
}
void modifyArray(int ar[], int m, int n) {
for (int i = 0; i < n; i++) {
if (ar[i] > m)
continue;
else {
int bits = setBitNumber(ar[i]);
int el = ar[i];
for (int j = 0; j < bits; j++) {
if (el & 1) {
el >>= 1;
el |= (1 << bits);
} else {
el >>= 1;
}
if (el > m) {
arr[i] = el;
break;
}
}
}
}
if (check(ar, m, n)) {
for (int i = 0; i < n; i++) cout << ar[i] << " ";
} else
cout << -1;
}
int main() {
int ar[] = {21, 22, 23, 19};
int n = sizeof(ar) / sizeof(ar[0]);
int m = 24;
modifyArray(ar, m, n);
return 0;
}
Output:
[26, 26, 27, 25]
The main operation performed in the program is the traversal of the array. It conducts the right shift operation on each element of the array ar[i]
.
The condition is checked if ar[i] > m
. If it’s true, then update array ar[i]
, else continue.
If any element of the array ar[i] ≤ m
, then print -1, else print the array ar[i]
.
Bit Shift and Mask in C++
A mask specifies which bits should be kept and which should be cleared.
Example:
Mask: 00001111b
Value: 01010101b
When we apply the mask on the value, we want to clear the first (upper) four bits while keeping the final (lower) four bits. As a result, we have retrieved the bottom four bits.
Output:
Mask: 00001111b
Value: 01010101b
Result: 00000101b
Bit shift operators are frequently used with masking operations to peel bits off a number one by one. The following example explains how to divide an unsigned char into an array of separate bits.
unsigned char y = 0xD5;
unsigned char bit[8];
unsigned char mask = 1;
for (int x = 7; x >= 0; x--) {
bits[x] = y & mask;
y = y >> 1;
}
Bit Shift for Negative Numbers in C++
Negative numbers should not be entered using the left and right shift operators. If either operand is a negative integer, the outcome is undefined behavior.
For example, the outcome of both 1 >> -1
and 1 << -1
is undefined.
#include <iostream>
int main() {
unsigned char x = -6, cout << "a>>1 = " << (a >> 1) << endl;
return 0;
}
Output:
error: undefined behavior in C
Bit Shift Using Long in C++
Data type long is used to bit shift by 32 bits or 64 bits.
Example:
For 32-bits,
unsigned long A = (1L << 37)
For 64-bits,
unsigned long long A = (1ULL << 37);
To implement the following using a program:
#include <stdio.h>
int main(void) {
long long y = 1ULL;
// Left shift 40 times
y <<= 20;
y <<= 20;
printf("y is %lld\n", y);
return 0;
}
Output:
y is 1099511627776
Here, a 64-bit variable long long y
is taken, and 1ULL is an unsigned long long int
constant (64 bits). The variable y
is shifted 40 times and is printed.
Conclusion
In this article, we have discussed the bit shift operator in C++. We learned about the left and right shift operators in C++ in detail.