Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a negative int greater than unsigned int? [duplicate]

int main(void)  {       unsigned int y = 10;       int x = – 4;       if (x > y)          Printf("x is greater");      else          Printf("y is greater");       getch();       return (0);  }   Output: x is greater 

I thought the output would be y is greater since it is unsigned. What's the reason behind this?

like image 448
Slashr Avatar asked Nov 28 '12 08:11

Slashr


2 Answers

Because the int value is promoted to an unsigned int. specifically 0xFFFFFFFC on a 32-bit machine, which as an unsigned int is 4294967292, considerably larger than 10

C99 6.3.1.1-p2

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.

To perform the conversion:

C99 6.3.1.3-p2

Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

Which basically means "add UINT_MAX+1" (as I read it, anyway).

Regarding why the promotion was to the unsigned int side; precedence:

C99 6.3.1.8-p1

...Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.

Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.

Which tells me int vs. unsigned char should work as expected.

Test

int main() {     int x = -4;     unsigned int y = 10;     unsigned char z = 10;      if (x > y)         printf("x>y\n");     else         printf("x<y\n");      if (x > z)         printf("x>z\n");     else         printf("x<z\n");     return 0; } 

Output

x>y x<z 

Well look at that.

like image 144
WhozCraig Avatar answered Oct 26 '22 06:10

WhozCraig


A comparison between a signed and an unsigned value will be made in "unsigned space". I.e., the signed value will be converted to unsigned by adding UINT_MAX + 1. In implementation using the 2-complement for negative values, no special handling of the values is required under the hood.

In this example, the -4 is turned into a 0x100000000-4 = 0xFFFFFFFC which is clearly > 10.

like image 26
glglgl Avatar answered Oct 26 '22 05:10

glglgl