HOWTO · C

Arithmetic Right Shift in C

Learn how C's single >> operator shifts unsigned values and why right-shifting a negative signed integer is not portable.

On this page

C has one right shift operator, >>. It shifts an integer value right by the number of bit positions given by its second operand. For an unsigned integer, the vacated high-order bits are filled with zeros. The result for a negative signed integer is not portable across C implementations, so do not assume that >> always performs an arithmetic right shift.

Shift Operators in C

C provides the binary operators << and >>. Each takes an integer value on the left and a shift count on the right. The expression value >> count shifts value right by count bit positions; the expression value << count shifts it left.

For example, value >> 1 shifts one position. Both operands undergo the integer promotions before the operation, so the type and value being shifted can differ from the declared type of a narrow integer object.

Types of Shift Operators in C

C does not have separate arithmetic and logical right-shift operators. The operator is always >>; the value’s type and value determine the applicable behavior. For an unsigned value, shifting right fills vacated high-order bits with zeros. For a nonnegative signed value, right shift gives the same result as dividing by the corresponding power of two.

A right shift of a negative signed integer is not portable. Implementations can differ in how they handle it, so copying the sign bit is not a guarantee you can rely on in portable code. This is why the phrase arithmetic right shift describes a behavior found on some implementations, not a second C operator. If your program depends on that behavior, document the compiler and target assumptions.

Run this example:

#include <stdio.h>

int main(void) {
    unsigned int value = 15u;
    int signed_value = -15;

    printf("unsigned: %u >> 1 = %u\n", value, value >> 1);
    printf("signed value: %d\n", signed_value);
    return 0;
}
unsigned: 15 >> 1 = 7
signed value: -15

The example prints unsigned: 15 >> 1 = 7 and signed value: -15. The unsigned expression 15u >> 1 yields 7 for every conforming width of unsigned int. The program prints the negative signed value but does not right-shift it, so it makes no claim about that value’s right-shift result.

The division analogy has limits: it is useful for unsigned values and nonnegative signed values, but it does not make a negative signed right shift portable. Also, the shift count must be nonnegative and smaller than the width of the promoted left operand; otherwise, the behavior is undefined. Do not assume that left shift always means multiplication by a power of two: signed overflow can make that operation undefined as well.

Conclusion

C uses one >> operator. Unsigned right shifts have defined zero-fill behavior, while the result of shifting a negative signed integer is not portable. Use unsigned values when you need predictable bit-level right shifts, and avoid relying on a particular signed behavior unless your implementation requirements explicitly permit it.