0
#include <stdio.h>
int main()
{
    unsigned int a=10;
    int b=10;
    int c=-1;
    printf("%d %d %d",(c%a),(c%(int)a),(c%b));
    return 0;
}

Outputs "5 -1 -1" (using https://www.onlinegdb.com/). What is it calculating to arrive at 5? And is just casting the unsigned int to int the correct fix as long as it fits in an int?

Pete
  • 79
  • 7

1 Answers1

3

All of C's arithmetic operators (except << and >> which only do this with the first operand) promote both operands to a common type before performing the operation, according the the language's rules for type promotion. Promoting c (with value -1) to unsigned performs modular reduction, modulo one plus the max value representable in the type, i.e. one plus UINT_MAX. The -1 cancels out with the "one plus", and the result is UINT_MAX, typically 4294967295. Then 4294967295U % 10U is of course 5.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 1
    As a side note: For systems with `sizeof(int) == 2`, `UINT_MAX` would be `65535`, which would give the same result. – mch Oct 08 '19 at 15:59
  • Ah thank you, that is embarassingly simple. (Though I wish it would cast in the other direction in the modulo case because that was confusing to find. Especially because it wasn't an uint but another type typedefed as uint which made it even less obvious.) – Pete Oct 08 '19 at 16:20
  • @mch: Further, the powers of 2 mod 10 are 2,4,8,6, repeating cyclically, so any unsigned type that is a whole number of 8-bit bytes (or even hex digits, i.e. 4-bit nibbles) will have -1 converted to that type congruent to 5 mod 10. – R.. GitHub STOP HELPING ICE Oct 08 '19 at 17:26