See this code snippet
int main()
{
unsigned int a = 1000;
int b = -1;
if (a>b) printf("A is BIG! %d\n", a-b);
else printf("a is SMALL! %d\n", a-b);
return 0;
}
This gives the output: a is SMALL: 1001
I don't understand what's happening here. How does the > operator work here? Why is "a" smaller than "b"? If it is indeed smaller, why do i get a positive number (1001) as the difference?
Binary operations between different integral types are performed within a "common" type defined by so called usual arithmetic conversions (see the language specification, 6.3.1.8). In your case the "common" type is
unsigned int
. This means thatint
operand (yourb
) will get converted tounsigned int
before the comparison, as well as for the purpose of performing subtraction.When
-1
is converted tounsigned int
the result is the maximal possibleunsigned int
value (same asUINT_MAX
). Needless to say, it is going to be greater than your unsigned1000
value, meaning thata > b
is indeed false anda
is indeed small compared to(unsigned) b
. Theif
in your code should resolve toelse
branch, which is what you observed in your experiment.The same conversion rules apply to subtraction. Your
a-b
is really interpreted asa - (unsigned) b
and the result has typeunsigned int
. Such value cannot be printed with%d
format specifier, since%d
only works with signed values. Your attempt to print it with%d
results in undefined behavior, so the value that you see printed (even though it has a logical deterministic explanation in practice) is completely meaningless from the point of view of C language.Edit: Actually, I could be wrong about the undefined behavior part. According to C language specification, the common part of the range of the corresponding signed and unsigned integer type shall have identical representation (implying, according to the footnote 31, "interchangeability as arguments to functions"). So, the result of
a - b
expression is unsigned1001
as described above, and unless I'm missing something, it is legal to print this specific unsigned value with%d
specifier, since it falls within the positive range ofint
. Printing(unsigned) INT_MAX + 1
with%d
would be undefined, but1001u
is fine.On a typical implementation where
int
is 32-bit, -1 when converted to anunsigned int
is 4,294,967,295 which is indeed ≥ 1000.Even if you treat the subtraction in an
unsigned
world,1000 - (4,294,967,295) = -4,294,966,295 = 1,001
which is what you get.That's why
gcc
will spit a warning when you compareunsigned
withsigned
. (If you don't see a warning, pass the-Wsign-compare
flag.)Find a easy way to compare, maybe useful when you can not get rid of unsigned declaration, (for example, [NSArray count]), just force the "unsigned int" to an "int".
Please correct me if I am wrong.
For this you need to understand the precedence of operators
Relational Operators works left to right ... so when it comes
if(1000>-1)
then first of all it will change -1 to unsigned integer because int is by default treated as unsigned number and it range it greater than the signed number
-1 will change into the unsigned number ,it changes into a very big number
The hardware is designed to compare signed to signed and unsigned to unsigned.
If you want the arithmetic result, convert the unsigned value to a larger signed type first. Otherwise the compiler wil assume that the comparison is really between unsigned values.
And -1 is represented as 1111..1111, so it a very big quantity ... The biggest ... When interpreted as unsigned.
while comparing a>b where a is unsigned int type and b is int type, b is type casted to unsigned int so, signed int value -1 is converted into MAX value of unsigned**(range: 0 to (2^32)-1 )** Thus, a>b i.e., (1000>4294967296) becomes false. Hence else loop printf("a is SMALL! %d\n", a-b); executed.