This is the code i've been able to come up:
isNegative(int a)
int result;
result = (a >> 31);
result = result & 1;
This works fine for all cases except for, 0x80000000. Please help as to how I can fix this code to be correct for all cases.
CodePudding user response:
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
isE1
right-shiftedE2
bit positions. IfE1
has an unsigned type or ifE1
has a signed type and a nonnegative value, the value of the result is the integral part of the quotient ofE1
/2E2
. IfE1
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;
}
CodePudding user response:
Here is an implementation that doesn't rely on implementation defined right-shifting and doesn't assume the size of an int
(but assumes two's complement representation):
#include <limits.h>
int isNegative(int a) {
return !!(a & INT_MIN);
}