How to Tell if a Right Shift in C is Arithmetic or Logical

In this tutorial, you will learn how to determine whether the right shift operation in C for signed values is arithmetic or logical. You will understand the difference between these two types of shifts, explore how C handles them, and learn how to test this behavior on your system using simple C code.

What is a Right Shift?

A right shift moves the bits of a number to the right by a specified number of positions. For example:

int x = 16;  // Binary: 00010000
int y = x >> 2; // Result: 00000100 (4 in decimal)

This operation drops the two rightmost bits and shifts in new bits on the left. But what those new bits are depends on the type of shift and whether the value is signed or unsigned.

Logical vs Arithmetic Right Shift

Arithmetic Right Shift: Preserves the sign bit. Negative numbers remain negative.

11110000 >> 2 = 11111100 (if arithmetic shift)

Logical Right Shift: Inserts zeros from the left.

advertisement
11110000 >> 2 = 00111100 (if logical shift)

Important Note:

In C, right-shifting a signed negative integer is implementation-defined. This means different compilers or systems might behave differently. However, most modern compilers (like GCC and Clang on x86) perform an arithmetic shift for signed integers.

For unsigned integers, right shift is always logical.

Free 30-Day Python Certification Bootcamp is Live. Join Now!

How to Check: A Simple Test Program

Here’s a quick way to test what your compiler does when right-shifting a signed negative number.

#include <stdio.h>
 
int main() {
    int num = -4;  // Example negative number
    int result = num >> 1;
 
    printf("Original number: %d\n", num);
    printf("After right shift: %d\n", result);
 
    if (result < 0)
        printf("Right shift is Arithmetic (sign bit preserved)\n");
    else
        printf("Right shift is Logical (zeros filled in)\n");
 
    return 0;
}

Optional: Add Bit-Level Output

To visualize the actual bit shift, you can include this helper function:

void print_binary(int n) {
    for (int i = sizeof(int) * 8 - 1; i >= 0; i--) {
        printf("%d", (n >> i) & 1);
    }
    printf("\n");
}

Then modify your main function:

print_binary(num);
print_binary(result);

What to Look For:

  • If the result is -2, your system uses arithmetic shift.
  • If the result is a large positive number, your system might be using a logical shift (rare for signed values).

Example Output (on most systems):

Original number: -4
After right shift: -2
Right shift is Arithmetic (sign bit preserved)

Best Practices

  • Avoid relying on right shifts of signed negatives unless you’re sure of compiler behavior.
  • For guaranteed logical shift on signed values:
  • unsigned int val = (unsigned int)signed_val;
    unsigned int result = val >> 1;
  • For arithmetic shift, use signed values and verify behavior during compilation.

Sanfoundry Global Education & Learning Series – 1000 C Tutorials.

advertisement
If you wish to look at all C Tutorials, go to C Tutorials.

advertisement
advertisement
Subscribe to our Newsletters (Subject-wise). Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!

Youtube | Telegram | LinkedIn | Instagram | Facebook | Twitter | Pinterest
Manish Bhojasia - Founder & CTO at Sanfoundry
I’m Manish - Founder and CTO at Sanfoundry. I’ve been working in tech for over 25 years, with deep focus on Linux kernel, SAN technologies, Advanced C, Full Stack and Scalable website designs.

You can connect with me on LinkedIn, watch my Youtube Masterclasses, or join my Telegram tech discussions.

If you’re in your 40s–60s and exploring new directions in your career, I also offer mentoring. Learn more here.