Reputation: 9204
I am trying to run the following code but confused with what's happening here:
int main()
{
/*
a = -1;
b = 0xffffffff;
*/
if(-1 == 0xffffffff )
printf("-1 is equal to maximum\n");
else
printf(" -1 is not equal to maximum\n");
if(0xff < -1)
printf(" Less than -1 \n");
if(0xff < 0xffffffff)
printf(" Less than maximum\n");
I tried with commented section as well and replaced -1 with "a" and 0xffffffff with "b" but the result is same .
It's 32 bit system so i have taken integer size 4 bytes.
My Output is :
-1 is equal to maximum
Less than maximum
If -1 is equal to maximum then it should execute both of the last two if statements. But it's not happening. Why?
Upvotes: 6
Views: 13554
Reputation: 920
In C/C++, negative numbers are stored in 2's compliment format and Most Significant Bit(MSB) acts as a sigh indication.
MSB 1 means -ve and MSB 0 means +ve. 1xxxxxxxxxx is -ve number and 0xxxxxxxxxx means +ve. In 1xxxxxxx the "xxxxxx" is 2's compliment of a number. And in 0xxxxxx the "xxxxx" is actual binary representation of a number.
Compiler interpret number as -ve if MSB(sign bit) is 1 and understands the number has to be the two's compliment.
First lets see what is 2's compliment:
2's compliment is negating an actual number(all bits) and then adding 1.
decimal 1 = 00000001
~ decimal 1 = 11111110
2's compliment of decimal 1 = 11111111 (F hex)
so -1 becomes = (1) 111111111111111
(1) is a MSB indicating -ve number the rest is the 2's compliment of a number.
thus -1 = 0xFFFFFFFF
You can try out printing binary representation of some -ve numbers and comparing the 2's compliment of binary representation of a number.
Upvotes: 3
Reputation: 279215
First thing, the results you see have nothing to do with the bit representation of signed integers, although they do have to do with the size.
When converted to unsigned, the value -1
is converted to the max value of the destination type. That's why -1 == 0xffffffff
. The bit representation of -1
doesn't affect anything.
0xff < -1
is false because both values are signed int
: 255 on the left and -1 on the right.
Finally, the reason -1 is converted to unsigned in the first comparison is that 0xffffffff
is too big for int
on your implementation (and for that matter on most implementations). However, it does fit in an unsigned int
(again on your implementation, and on most implementations other than those for 16 bit machines). In order to compare an unsigned int against a signed int, C converts the signed int to unsigned. This gives surprising results (including the surprise that -1 is somehow equal to a positive number), which is why most style guides tell you to avoid mixing signed and unsigned types. But it's too late to change the language.
Upvotes: 0
Reputation: 476930
I'll quote this from C++; I think it's the same for C:
The literal -1
is always a signed int
.
The literal 0xff
is a signed int
, but 0xffffffff
is an unsigned int
.
In comparisons of mixed signs, both operands are converted to unsigned, explaining all your results.
Here's the rule about the types of naked integral literals (i.e. without type suffix) from C++11, table 6:
Decimal literals are of the smallest type among int
, long int
or long long int
, whichever fits.
Hexadecimal literals are of the smallest type among int
, unsigned int
, long int
, unsigned long int
, long long int
, unsigned long long int
, whichever fits.
To spell it out again:
In your first comparison, both sides are converted to unsigned int
, giving the value 0xFFFFFFFF
.
In the second comparison, both terms are signed integers, and the left term is 255
and the right term is -1
.
In the third comparison, both terms are converted to unsigned int
.
Observe that we never needed to worry about hardware implementations of signedness for this question. The only relevant platform-dependent value is the size of int
, which we used when we asserted that 0xffffffff
does not fit into an int
but does fit into an unsigned int
.
Upvotes: 5
Reputation: 328536
0xffffffff
is equal to -1
since the int
type has only four bytes and the two-complement of -1
is 0xffffffff
in memory (-1 == (~1) + 1
). So the compiler has no way to tell -1
and 0xffffffff
apart - there simply isn't room for that in memory.
0x000000ff
is equivalent to 255
which is bigger than -1
, so the last two if
s won't get executed.
What might be confusing you is this:
char c = 0xff;
if( c == -1 ) {
printf("char 0xff is -1");
}
In this case, I compare a char
with an int
, so the compiler will have to expand the 8-bit char
type. Since char
is signed, the sign (uppermost bit) will be preserved and you'll get -1
(int).
This is an example why you need to be careful when mixing signed/unsigned types and types of different widths.
Upvotes: 0