I need to perform a real mathematical modulo in C. It makes sense for me to allow negative numbers for the moduled argument, since my modular calculations can produce negative intermediate results, which must be put back into the least residue system. But it makes no sense to allow negative module, therefore i wrote
unsigned int mod( int x, unsigned int m )
{
int r = x % m;
return r >= 0 ? r : r + m;
}
However calling such function with negative number and positive module
printf("%u\n", mod(-3, 11));
produces output
1
And i don't understand why. Could you please explain?
EDIT: I know operator % is different from mathematical modulo and i know how it is defined for positive and negative numbers. I was asking what it will do for different signedness, not different sign.
clang
with -Wconversion
enabled clearly pinpoints your mistake:
prog.cc:3:15: warning: implicit conversion changes signedness: 'unsigned int' to 'int' [-Wsign-conversion]
int r = x % m;
~ ~~^~~
prog.cc:3:13: warning: implicit conversion changes signedness: 'int' to 'unsigned int' [-Wsign-conversion]
int r = x % m;
^ ~
prog.cc:4:21: warning: operand of ? changes signedness: 'int' to 'unsigned int' [-Wsign-conversion]
return r >= 0 ? r : r + m;
~~~~~~ ^
prog.cc:4:25: warning: implicit conversion changes signedness: 'int' to 'unsigned int' [-Wsign-conversion]
return r >= 0 ? r : r + m;
^ ~
prog.cc:9:12: warning: implicit conversion changes signedness: 'unsigned int' to 'int' [-Wsign-conversion]
return mod(-3, 11);
~~~~~~ ^~~~~~~~~~~
When converted to unsigned int
, -3
becomes 4294967293
.
4294967293 % 11
is equal to 1
.