Equivalent of modulus (math function) in C?
Question
I have a piece of code where I see a warning saying
I am doing a comparison between signed and unsigned number .
Something like int <= CONSTANT/sizeof(expression)
What is the best way to correct this? I believe to take the modulus of signed number and then do the comparison, right? I mean I get the unsigned number after division by sizeof operator on an expression. So the other way could be to make this rhs signed
If so is there a function in c that would let me do this? I did a quick search and they say % for modulo which obviously is not what I am looking for.
This is the actual warning
warning: comparison between signed and unsigned integer expressions
and this is the actual line of code
functionA( ......, int num, .....) {
assert( num <= MAX_SIZE/sizeof(int));//where MAX_SIZE is #define MAX_SIZE 1000
}
Solution
Just cast one side to the other signedness. You have to make sure that the signed number is not negative if you cast that to unsigned - otherwise a comparison of -1 < 100
will not have the desired outcome, since (unsigned)(-1) == UINT_MAX
-, or that the unsigned number doesn't overflow if you cast that to signed. In those cases, add an additional condition to treat them.
For the above particular case, I would use
assert(num <= (int)(MAX_SIZE/sizeof(int)));
// num <= MAX_SIZE/(int)sizeof(int) if I'm in a mean mood
if num
might be negative and
assert((unsigned)num <= MAX_SIZE/sizeof(int));
if num
is guaranteed to be nonnegative.
OTHER TIPS
If you know the right operand is <= INT_MAX
, you can cast it to int
.
int bla;
...
if (bla < (int) sizeof expr) {
...
}
But if you can change the type of object bla
to size_t
(which is the type of the value that sizeof
yields) it would be even better than to cast.
As I see this, your int num
is allowed to take any negative value and positive values up to MAX_SIZE/sizeof(int)
. Otherwise you would have declared num
as an unsigned integer for sure...
Would extending your assertion statement by this additional condition help in your case?
assert( num < 0 || /* make the signed check */
(unsigned int)num <= MAX_SIZE/sizeof(int) /* the unsigned remainder */
);