If you know the representation is 2's complement, then you can do:
#include <stdio.h>
#define IS_NEG(a) (!!((1 << 31) & (a)))
int main(void)
{
int n;
while(1) {
scanf("%d", &n);
printf("negative: %d\n", IS_NEG(n));
}
return 0;
}
Explanation:
(1 << 31) will take the number 1 and shift it 31 times to the left, thus giving you 1000 0000 0000 0000 0000 0000 0000 0000. If you don't want to use the shift, you could use 0x80000000 too.
& (a) does a bitwise test with that big binary number. Since an AND operation only returns TRUE when both operands are TRUE, it follows that only if your number is negative (in 2's complement representation) that this will return TRUE.
!!(...) This double negation accounts for the fact that when you do that bitwise AND, the returned value by the expression will be (1 << 31) if the number is really negative. So we invert it (giving us zero), than invert it again (giving us 1). Therefore, this ensures that we get a ZERO or a ONE as a final result.
IS_NEG will return 0 on positive numbers AND 0, and returns 1 on all negative numbers.
Since the MSB will be a one when the number is negative, just test that bit. Note that this will only work for 32 bit integers (so you have to check that with a sizeof(int). The example returns 1 if a number is negative, but should be no problem reworking it to return 1 for positive numbers.
Let me know if this doesn't solve the problem. As I understand, you just want to test if any given int is positive/negative.
Edit: From the comments, I made a program to help you see what's going on.
#include <stdio.h>
#define IS_NEG(a) (!!(0x80000000 & (a)))
char buf[65];
/* converts an integer @n to binary represention of @bits bits */
char *bin(int n, unsigned int bits)
{
char *s = buf;
for(bits = (1 << (bits - 1)); bits > 0; bits = bits >> 1)
/* look! double negation again! Why this? :) */
*s++ = !!(n & bits) + 48;
*s = 0;
return buf;
}
int main(void)
{
/* R will be our partial result through-out the loop */
int r, n;
while(1) {
/* get the number */
scanf("%d", &n);
/* this is the inner part of the macro
* after this, we could say IS_NEG "becomes"
* (!!(r))
*/
r = n & 0x80000000;
printf("n & 0x80000000: 0x%x\n", r);
printf(" n = %s\n", bin(n, 32));
printf(" r = %s\n", bin(r, 32));
/* now we print what R is, so you see that the bitwise AND will
* return 0x80000000 on negative numbers. It will also print
* the NEGATION of R...
*
* After the printf(), we just assign the negated value to R.
*/
printf("r = 0x%x, !r = 0x%x\n", r, !r);
r = !r;
printf(" r = %s\n", bin(r, 32));
/* After this, IS_NEG "becomes" (!(r)) */
/* In the MACRO, this would be the second negation. */
printf("r = 0x%x, !r = 0x%x\n", r, !r);
r = !r;
printf(" r = %s\n", bin(r, 32));
/* Now, if R is 0, it means the number is either ZERO or
* POSITIVE.
*
* If R is 1, then the number is negative
*/
}
return 0;
}