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 = 8

How >> Works

  1. Read current binary value.
  2. Move all bits right by shift count.
  3. Low bits drop off from the right edge.
  4. 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 >> 1 often behaves like value / 2.
  • value >> 2 often behaves like value / 4.
  • For signed negative values, behavior can differ by implementation, so use care.
ValueExpressionResult
6464 >> 132
6464 / 232
6565 >> 132

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 3

This 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 byte or uint8_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

  1. shiftedValue = rawSensor >> stepIndex reduces value by bit shift.
  2. dividedValue shows the matching arithmetic pattern for comparison.
  3. extractedBit = (flags >> 4) & 1 reads one selected flag bit.
  4. shiftedValue & ledMask checks lowest bit after shifting.
  5. LED turns ON when the lowest bit is 1, otherwise OFF.
  6. Serial output compares binary movement, arithmetic result, and extracted flag bit.

What Happens Inside

  1. CPU loads the source bits.
  2. Bits move right by shift count.
  3. Right-edge bits are discarded.
  4. New value is stored and used in conditions.
StepExpressionBinary ResultDecimal
1128 >> 010000000128
2128 >> 10100000064
3128 >> 20010000032

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) & 1 for 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.

Run in Simulator