简体   繁体   中英

C unsigned int + int

Why does this code print "greater than 0" ?

int main()
{
  unsigned int a = 5;
  int b = -10;
  (a + b) > 0 ? printf("greater than 0") : printf("less than 0");
}

If I do:

printf("%d\n", a + b);

...it prints:

-5 

Whenever you do any operation in C, the arguments are converted according to the "Usual arithemetic conversions" rules (section 6.3.1.8 of the spec). There are lots of them, but for the purposes of this example, the important one is:

the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:
If both operands have the same type, then no further conversion is needed.
Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
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.

int and unsigned int have the same coversion rank, so whenever you do an operation on an int and an unsigned int , the int will be converted to unsigned .

In you case, that causes the value of b (-10) to become a very large number. You then add 5 to it, which is still very large (but not large enough to wrap around back to zero), so the result of > is true.

6.3.1.1 Boolean, characters, and integers and 6.3.1.8 Usual arithmetic conversions (thanks Chris)

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.58) All other types are unchanged by the integer promotions.

and

...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.

You addition involves an unsigned and an int , int cannot represent all values of unsigned , so the value is converted to an unsigned int .

Your problem

By default, your int gets promoted to an unsigned int , according to the usual arithmetic conversions :

[...] 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.

Solution

You need to cast a to int for this ternary to work as you expect:

((int)a + b) > 0 ? printf("greater than 0") : printf("less than 0");

In your print statement, you are converting a and b to their signed int representation before you add them together. You are not doing so for your conditional.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM