0
#include <stdio.h>

int main(void) {
    unsigned int n = 10;
    char m = -1;
    if (m < n)
        printf("m < n\n");
    else
        printf("m > n\n");
    printf("m + n = %u\n", m + n);
    return 0;
}

When I run this code in MinGW64 on windows. It prints "m > n","m + n = 9" I can't understand why "m + n = 9" and "m > n".

Jens
  • 69,818
  • 15
  • 125
  • 179
flywen
  • 39
  • 3
  • `char` is not guaranteed to be signed. You likely have an unsigned `char` type, so -1 is really 255. – Jason Feb 08 '23 at 14:16
  • 2
    @Jason In this specific case the signedness doesn't matter. `unsigned char` should give the same result `m > n`. As would `signed char`. – Lundin Feb 08 '23 at 14:18
  • @Lundin, you are correct. That is very not intuitive. – Jason Feb 08 '23 at 14:22
  • 1
    @ikegami In post/edit history. But I guess there's a specific issue in this question, `unsigned char` gives value 0xFF but `signed char` 0xFFFFFFFF because in the former case the sign conversion happens upon assignment and in the latter case upon implicit promotion. – Lundin Feb 08 '23 at 14:23
  • I added the "is char signed" canonical dupe to the duplicate list too, since it does matter for the 9 vs 256 result. – Lundin Feb 08 '23 at 14:25
  • 1
    It is not critical here, but if `m < n` is false, the condition is `m >= n`, not `m > n`. – Jonathan Leffler Feb 08 '23 at 14:25
  • The TL;DR: If `char` is signed it gets value -1, then in `m < n` the usual arithmetic conversions convert it to 0xFFFFFFFF. m + n turns into 4294967295 + 10. If `char` is unsigned it gets value 255 (as per modulo UCHAR_MAX+1), 255 > 10, 255 + 10 = 265. – Lundin Feb 08 '23 at 14:30
  • @Jason: If `char` were unsigned and `m` were 255, `m+n` would be 265, not 9. – Eric Postpischil Feb 08 '23 at 14:47
  • flywen, To full-range compare these potentially mixed signed types for `<`, use `m < 0 || m < n`. – chux - Reinstate Monica Feb 08 '23 at 15:42

1 Answers1

2

I can't understand why "m + n = 9" and "m > n".

You can only compare compatible integers so char is being converted to unsigned int and its value is (assuming 32 bits integers and two complement negative integers) 0xffffffff which is much more than 10.

When you add char is converted to unsigned int and added. Two complements addition of such converted negative number gives the correct value (it acts like substraction). More information: https://en.wikipedia.org/wiki/Two%27s_complement

0___________
  • 60,014
  • 4
  • 34
  • 74