Article by Ayman Alheraki on January 11 2026 10:34 AM
In C++, shift operators are used for bitwise manipulation of data. These operators allow you to shift the bits of a number to the left or right, effectively multiplying or dividing the number by powers of two. They are commonly used in low-level programming, such as hardware control, cryptography, and optimization.
Shift operators are represented by << for left shift and >> for right shift.
Left Shift Operator (<<)
The left shift operator shifts the bits of its left operand to the left by the number of positions specified by its right operand.
Each left shift multiplies the number by 2.
Bits that are shifted beyond the size of the data type are discarded, and the vacant positions are filled with 0.
Syntax:
result = number << shift_count;Example:
using namespace std;
int main() { int num = 3; // Binary: 0000 0011 int result = num << 1; // Shift bits left by 1
cout << "3 << 1 = " << result << endl; // Output: 6 (0000 0110) return 0;}Explanation:
The binary representation of 3 is 0000 0011.
Shifting left by 1 results in 0000 0110, which equals 6.
Right Shift Operator (>>)
The right shift operator shifts the bits of its left operand to the right by the number of positions specified by its right operand.
Each right shift divides the number by 2.
Vacant positions are filled differently based on the data type (signed or unsigned):
Unsigned integers: Vacant positions are filled with 0.
Signed integers
: It depends on the implementation (logical or arithmetic right shift):
Logical shift: Vacant positions are filled with 0.
Arithmetic shift: Vacant positions are filled with the sign bit (preserving the number's sign).
Syntax:
result = number >> shift_count;Example:
using namespace std;
int main() { int num = 12; // Binary: 0000 1100 int result = num >> 2; // Shift bits right by 2
cout << "12 >> 2 = " << result << endl; // Output: 3 (0000 0011) return 0;}Explanation:
The binary representation of 12 is 0000 1100.
Shifting right by 2 results in 0000 0011, which equals 3.
With the introduction of Modern C++, shift operators are primarily used for bitwise operations, especially when manipulating hardware registers or creating efficient low-level algorithms. However, there are a few points to note:
Integer Promotion and Undefined Behavior
In C++, the right operand of a shift must be non-negative and less than the number of bits in the left operand. Violating this can lead to undefined behavior.
Modern C++ provides std::clamp() and other safeguards to avoid undefined behavior during shifts.
Use of std::bitset for Bit Manipulation
Modern C++ encourages the use of the std::bitset class for bit manipulation. This provides a safer and more expressive way to manage bits.
With std::bitset, you can easily visualize, manipulate, and manage individual bits without directly working with shift operators.
Example with std::bitset:
using namespace std;
int main() { bitset<8> bits(3); // Binary: 00000011 cout << "Original bits: " << bits << endl;
// Shift left bits <<= 1; cout << "After left shift by 1: " << bits << endl;
// Shift right bits >>= 2; cout << "After right shift by 2: " << bits << endl;
return 0;}Output:
Original bits: 00000011After left shift by 1: 00000110After right shift by 2: 00000001Safe Shifting with std::bitset
When you use std::bitset, you are protected against shifting by more than the number of bits in your type, as std::bitset operations are defined and safe.
Unlike primitive types, std::bitset won’t allow undefined behavior from out-of-range shifts.
In C++, shifting signed integers can be tricky because of the difference between logical and arithmetic shifts.
Unsigned integers always use logical shifts:
Left shift fills with 0.
Right shift fills with 0.
Signed integers may use arithmetic shifts, which preserve the sign bit:
Left shift fills with 0.
Right shift fills with the sign bit (for negative numbers).
Example of Signed Right Shift:
using namespace std;
int main() { int num = -8; // Binary (assuming 32-bit): 11111111111111111111111111111000 int result = num >> 2; // Arithmetic right shift
cout << "-8 >> 2 = " << result << endl; // Output: -2 (Binary: 11111111111111111111111111111110) return 0;}Efficient Multiplication and Division:
Left shifting multiplies a number by 2^n, while right shifting divides by 2^n.
Example:
int x = 4; int multiply_by_8 = x << 3; // Multiply by 8 (2^3)int divide_by_4 = x >> 2; // Divide by 4 (2^2)Setting and Clearing Specific Bits:
You can use shift operators to manipulate specific bits in a number, especially in systems programming or embedded development.
Example: Set the 3rd bit of a number:
int num = 5; // Binary: 0000 0101num |= (1 << 2); // Set 3rd bit (counting from 0)cout << num; // Output: 7 (Binary: 0000 0111)Bit Masking:
Shift operators are used in combination with bitwise AND/OR to create or manipulate masks for selective bit manipulation.
Example: Clear the 2nd bit:
int num = 7; // Binary: 0000 0111num &= ~(1 << 1); // Clear the 2nd bitcout << num; // Output: 5 (Binary: 0000 0101)Shift operators (<< and >>) are powerful tools in C++ for manipulating individual bits of a number. They have various practical applications, including optimization, cryptography, and embedded systems development. In Modern C++, while these operators are still relevant, features like std::bitset make bit manipulation more robust and less prone to errors, allowing for safer handling of binary data. Always be cautious of undefined behavior when shifting beyond the bit limits of your types.