The code posted has implementation behavior: Right shifting a signed negative value is specified as implementation-defined by the C Standard:
6.5.7 Bitwise shift operators
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
/2E2
. If E1
has a signed type and a negative value, the resulting value is implementation-defined.
Conversely, conversion from signed int
to unsigned
is fully defined and right shifting the unsigned value will work as expected.
Note that if the width of the unsigned
type is exactly 32 bits, masking the result of the right shift is not required. Regarding the behavior on INT_MIN
: if signed integers are represented using two's complement, converting INT_MIN
to unsigned
produces 0x80000000
, which gives 1
when shifted right by 31 bits, as expected since INT_MIN
is negative.
Here is a modified version:
#include <stdint.h>
// assuming 32-bit ints
int isNegative(int32_t a) {
uint32_t result = a;
return result >> 31;
}