0

I have the following code :

#include <stdio.h> #include <stdlib.h>

int main(void) {
    unsigned int a = -1;
    int b = -1;
    if (a<b)
    {
        printf("a<b");
    }
    else if (a>b)
    {
        printf("a>b");
    }
    else
    {
        printf("a=b");
    }


    return 1;
}

I predicted the result would be a> b, because the value of a would be 4294967295, but the result was different: a = b !!

Could someone explain what the unsigned word is for? because I don't see any effect using it here!

thanks !

  • 1
    An `int` will be promoted to `unsigned int` during a comparison. – babon Jun 10 '21 at 11:17
  • The rank plays a roll in the direction of conversion, btw. At the risk of seeming self-gratifying, [you may find this interesting](https://stackoverflow.com/questions/13600991/why-is-a-negative-int-greater-than-unsigned-int/13601259#13601259). – WhozCraig Jun 10 '21 at 11:31

5 Answers5

2

When you do a comparison between a and b, b will be promoted to unsigned int for the purposes of the comparison only, so the values will compare equal.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
0

The unsigned type qualifier does not change the bit pattern of an integer, only its interpretation, so both a and b contain the same bit pattern 0xFFFFFFFF(for 32bit int your platform may differ - this is illustrative only).

Then when you compare and int to an unsigned int the int is implicitly "promoted" to unsigned. The promotion is also a matter of interpretation only and the bit pattern does not change, so you are comparing 0xFFFFFFFF with 0xFFFFFFFF and they are equal (identical bit pattern).

Clifford
  • 88,407
  • 13
  • 85
  • 165
0

The < or > operator will cause the int variable to be promoted to unsigned int as one of the operands is unsigned.

So, just when you compare, your -1 in b gets promoted to an unsigned int and essentially becomes the same as the bit pattern in a. Thus resulting in the first two if conditions being false and the else part being executed.

babon
  • 3,615
  • 2
  • 20
  • 20
0

The initialization of unsigned a with an out-of-range int value causes a conversion that is effectively a "mod" UINTMAX+1:

... 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. C17 § 6.3.1.3 2

unsigned int a = -1;
// `a` has the value of UINTMAX (typically 4294967295)  

I predicted the result would be a> b, because the value of a would be 4294967295

a does have the value of 4,294,967,295, but so does b.

When two objects are compared that differ in type, one is converted. In this case, the int -1 is converted to unsigned with the same result as above: UINTMAX.

int b = -1;
// Same as `a<(unsigned)b` or `a<UINTMAX` which is false.
if (a<b)

Result of OP's if chain is printf("a=b");

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

The word unsigned denotes exactly what it means. That is in this declaration

unsigned int a = -1;

the variable a has unsigned integer type that means the range of values that can be stored in the variable is [0, UINT_MAX].

The initializer -1 is implicitly converted to the type of the initialized object by propagating the sign bit (if required) for the two's complement internal representation of integers. As a result as all bits are set the value of the expression (unsigned int )-1 is the maximum value for the type unsigned int.

In conditions like the condition in this if statement

if (a<b)

the common type of operands is deduced. Due to the usual arithmetic conversions as the variables a and b have the same conversion rank then the object b of the type int is converted to the type unsigned int.

And in fact there are compared ( unsigned int )-1 with ( unsigned int )-1 that are equal each other expressions.

From the C Standard (6.3.1.8 Usual arithmetic conversions)

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.

The ranks of the types unsigned int and int are the same.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335