Comparison operation for unsigned integers

See this code snippet

int main() { unsigned int a = 1000; int b = -1; if (a>b) printf("A is BIG! %d\n", ab); else printf("a is SMALL! %d\n", ab); return 0; } 

This gives the result: a SMALL: 1001

I donโ€™t understand what is going on here. How does operator> work here? Why is a a less than b? If it's really less, why am I getting a positive number (1001) as the difference?

+33
c gcc unsigned signed
Jan 18 '10 at 9:21
source share
5 answers

Binary operations between different integral types are performed in a โ€œgeneralโ€ type defined by the so-called ordinary arithmetic transformations (see language specification, 6.3.1.8). In your case, the "generic" type is unsigned int . This means that the operand int (your b ) is converted to unsigned int before comparison, as well as for performing subtraction.

When -1 converted to unsigned int , the result is the maximum possible value of unsigned int (same as UINT_MAX ). Needless to say, it will be greater than the unsigned value of 1000 , which means that a > b really false and a really small compared to (unsigned) b . if in your code should resolve to else branches, as was the case in your experiment.

The same conversion rules apply to subtraction. Your ab really interpreted as a - (unsigned) b , and the result is of type unsigned int . Such a value cannot be printed using the %d format specifier, since %d only works with signed values. Your attempt to print it with %d leads to undefined behavior, so the value that you see printed (even if it has a logical deterministic explanation in practice) makes absolutely no sense from the point of view of C.

Edit: Actually, I could be wrong about undefined behavior. According to the specification of the C language, the common part of the range of the corresponding type, with and without signature, must have an identical representation (meaning, according to footnote 31, "interchangeability as arguments for functions"). Thus, the result of the expression a - b not specified 1001 , as described above, and if I do not miss something, it is legal to print this unsigned value with the %d specifier, since it falls into the positive range of int . Printing (unsigned) INT_MAX + 1 with %d will be undefined, but 1001u is fine.

+44
Jan 18 '10 at 9:37
source share

In a typical implementation, where int is 32-bit, -1 when converting to unsigned int is 4,294,967,295, which is really โ‰ฅ 1000.

Even if you are considering subtraction in the unsigned world, 1000 - (4,294,967,295) = -4,294,966,295 = 1,001 what you get.

This is why gcc spit out a warning when comparing unsigned to signed . (If you do not see the warning, skip the -Wsign-compare flag.)

+13
Jan 18 '10 at 9:25 am
source share

You are doing an unsigned comparison, i.e. comparing 1000 to 2 ^ 32 - 1.

The output is signed due to% d in printf.

NB Sometimes the behavior when you mix signed and unsigned operands depends on the compiler. I think it's best to avoid them and throw when in doubt.

0
Jan 18 '10 at 9:23
source share

Find a simple comparison method, perhaps useful when you cannot get rid of an unsigned declaration (for example, [NSArray count]), just force "unsigned int" into "int".

Please correct me if I am wrong.

 if (((int)a)>b) { .... } 
0
Apr 02 2018-12-12T00:
source share

The hardware is designed to compare signed and unsigned signatures.

If you want an arithmetic result, first convert the unsigned value to a larger signed type. Otherwise, the compiler will assume that the comparison is valid between unsigned values.

And -1 is represented as 1111..1111, so this is a very large number ... The largest ... When interpreted as unsigned.

0
Apr 20 2018-12-12T00:
source share



All Articles