Operators
Lesson 55: Using >> Bitshift Right Operator
Learn how >> shifts bits to the right, scales values down by powers of two, and supports bit-mask logic.
Progress indicator
Lesson 55 of 57
Learning Objectives
- Understand what right shift (>>) does at bit level.
- Read and predict right-shift results in binary and decimal forms.
- Compare >> with divide-by-2 behavior and know where differences appear.
- Use >> with masks to extract specific bit values from flags.
- Understand signed vs unsigned shift behavior for safer embedded code.
- Avoid common sign, width, and invalid shift-count mistakes.
Concept Explanation
What is the Right Shift Operator (>>)
The >> operator moves bits to the right by a shift count.
Right Shift Syntax
result = value >> shiftCount;
int x = 32 >> 2; // x = 8How >> Works
- Read current binary value.
- Move all bits right by shift count.
- Low bits drop off from the right edge.
- Store the new reduced bit pattern.
Example: 20 in binary is 00010100. After 20 >> 2, it becomes 00000101 (which is 5).
Bit Movement Concept
128 = 10000000
128 >> 1 = 01000000 (64)
128 >> 2 = 00100000 (32)
128 >> 3 = 00010000 (16)>> vs Divide by 2 (Comparison)
value >> 1often behaves likevalue / 2.value >> 2often behaves likevalue / 4.- For signed negative values, behavior can differ by implementation, so use care.
| Value | Expression | Result |
|---|---|---|
| 64 | 64 >> 1 | 32 |
| 64 | 64 / 2 | 32 |
| 65 | 65 >> 1 | 32 |
Using >> with Bit Masks
You can move a target bit down to bit 0 and then test it with mask 1.
byte flags = 0b00101000;
byte target = (flags >> 3) & 0b00000001; // read original bit 3This pattern is very common in embedded work when reading packed status bits from sensors or protocol bytes.
Signed vs Unsigned Right Shift
- Unsigned values usually shift in zeros from the left.
- Signed negative values may keep the sign bit depending on compiler behavior.
- For clean bit extraction, prefer unsigned types like
byteoruint8_t.
When to Use >>
- Scaling down power-of-two values quickly.
- Extracting specific bits from flags/registers.
- Packing/unpacking bit-based protocols.
Example Code
This sketch shifts a value right, compares it with divide-by-power-of-two logic, and uses a mask to control LED state.
const int LED_PIN = 2;
byte ledMask = 0b00000001;
int rawSensor = 128;
int stepIndex = 0;
byte flags = 0b10110000;
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
}
void loop() {
int shiftedValue = rawSensor >> stepIndex;
int dividedValue = rawSensor / (1 << stepIndex);
byte extractedBit = (flags >> 4) & 0b00000001;
if (shiftedValue & ledMask) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
Serial.print("stepIndex=");
Serial.print(stepIndex);
Serial.print(", shiftedValue=");
Serial.print(shiftedValue, BIN);
Serial.print(", dividedValue=");
Serial.print(dividedValue);
Serial.print(", extractedBit=");
Serial.println(extractedBit);
delay(500);
stepIndex = stepIndex + 1;
if (stepIndex > 4) {
stepIndex = 0;
}
}Example Code Explanation
shiftedValue = rawSensor >> stepIndexreduces value by bit shift.dividedValueshows the matching arithmetic pattern for comparison.extractedBit = (flags >> 4) & 1reads one selected flag bit.shiftedValue & ledMaskchecks lowest bit after shifting.- LED turns ON when the lowest bit is 1, otherwise OFF.
- Serial output compares binary movement, arithmetic result, and extracted flag bit.
What Happens Inside
- CPU loads the source bits.
- Bits move right by shift count.
- Right-edge bits are discarded.
- New value is stored and used in conditions.
| Step | Expression | Binary Result | Decimal |
|---|---|---|---|
| 1 | 128 >> 0 | 10000000 | 128 |
| 2 | 128 >> 1 | 01000000 | 64 |
| 3 | 128 >> 2 | 00100000 | 32 |
Common Mistakes with >>
- Shifting by invalid or too-large counts for the variable width.
- Assuming signed negative values always shift the same way everywhere.
- Using decimal literals without checking real binary intent.
- Forgetting parentheses in combined expressions, leading to wrong precedence.
Best Practices for >>
- Use unsigned types when extracting raw bit fields.
- Document bit positions using named constants.
- Print values in binary during debugging and learning.
- Use parentheses like
(flags >> bitPos) & 1for readability. - Validate shift counts before use in runtime-generated expressions.
Try it now
Open the simulator workspace and inspect right-shift behavior with bit extraction.