16jacobj
16jacobj

Reputation: 493

Bizarre right bitshift inconsistency

I've been working with bits in C (running on ubuntu). In using two different ways to right shift an integer, I got oddly different outputs:

#include <stdio.h>
int main(){
int x = 0xfffffffe;
int a = x >> 16;
int b = 0xfffffffe >> 16;
printf("%X\n%X\n", a, b);
return 0;
}

I would think the output would be the same for each: FFFF, because the right four hex places (16 bits) are being rightshifted away. Instead, the output is:

FFFFFFFF
FFFF

What explains this behaviour?

Upvotes: 1

Views: 123

Answers (2)

Sydney Hauke
Sydney Hauke

Reputation: 171

The behaviour you see here has to do with shifting on signed or unsigned integers which give different results. Shifts on unsigned integers are logical. On the contrary, shift on signed integers are arithmetic. EDIT: In C, it's implementation defined but generally the case.

Consequently,

int x = 0xfffffffe;
int a = x >> 16;

this part performs an arithmetic shift because x is signed. And because x is actually negative (-2 in two's complement), x is sign extended, so '1's are appended which results in 0xFFFFFFFF.

On the contrary,

int b = 0xfffffffe >> 16;

0xfffffffe is a litteral interpreted as an unsigned integer. Therefore a logical shift of 16 results in 0x0000FFFF as expected.

Upvotes: 2

tadman
tadman

Reputation: 211740

When you say:

int x = 0xfffffffe;

That sets x to -2 because the maximum value an int can hold here is 0x7FFFFFFF and it wraps around during conversion. When you bit-shift the negative number it gets weird.

If you change those values to unsigned int it all works out.

#include <stdio.h>
int main(){
  unsigned int x = 0xfffffffe;
  unsigned int a = x >> 16;
  unsigned int b = 0xfffffffe >> 16;
  printf("%X\n%X\n", a, b);
  return 0;
}

Upvotes: 4

Related Questions