Bitshift Causing Overflow When It Shouldn't

1

When I am bitshifting the max positive 2's complement, shouldn't shifting it 31 bits make an effective 0 because it starts as 0111 1111, etc.

I have tried decreasing the shift but I am assuming it's just the computer reading it incorrectly.

int main(void) 
{
  int x = 0x7FFFFFFF;
  int nx = ~x;
  int ob = nx >> 31;
  int ans = ob & nx;

  printf("%d",ans);
}

I am expecting ob to be 0 but it turns out as the twos complement minimum. I am using this to create a bang without actually using !.

c
linux
bit-shift
asked on Stack Overflow Sep 11, 2019 by Kenneth Straw • edited Sep 11, 2019 by dbush

1 Answer

3

If you were shifting the max positive two's complement number, it would end up as zero.

But you are not shifting that number:

int x = 0x7FFFFFFF;
int nx = ~x;          // 0x80000000 (assuming 32-bit int).

You are bit-shifting the largest (in magnitude) negative number.

And, as per the standards document C11 6.5.7 Bitwise shift operators /5 (my emphasis):

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2^E2 . If E1 has a signed type and a negative value, the resulting value is implementation-defined.

Your implementation seems to preserve the sign bit, which is why you end up with the non-zero negative value.


As an aside, if you want a ! operator, you can just use:

output = (input == 0);

See afore-mentioned standard, 6.5.3.3 Unary arithmetic operators /5 (again, my emphasis) where it explicitly calls out the equivalence:

The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E).

answered on Stack Overflow Sep 11, 2019 by paxdiablo • edited Sep 11, 2019 by paxdiablo

User contributions licensed under CC BY-SA 3.0