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 !.

1
  • It is implementation-defined behavior whether or not the sign-bit shifts for signed numbers. Commented Sep 11, 2019 at 2:58

1 Answer 1

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).

Sign up to request clarification or add additional context in comments.

3 Comments

Of course, thank you. However, one more question, why does ob come out to -1 (as per my tests) when we shift 0x80000000 31 bits to the right?
@KennethStraw: if you're getting -1, your implementation both preserves the sign bit and shifts it into the leftmost magnitude bit. Hence you see 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, 0xfc000000, all the way to 0xffffffff.
Thank you so much that clears a lot up, and as for the ! operator I am only allowed to use ~ & ^ | + << and >> operators. Still, thank you so much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.