Modulo operation with negative numbers

In a C program I was trying the below operations (Just to check the behavior)

 x = 5 % (-3);
 y = (-5) % (3);
 z = (-5) % (-3); 

printf("%d ,%d ,%d", x, y, z); 

It gave me output as (2, -2 , -2) in gcc. I was expecting a positive result every time. Can a modulus be negative? Can anybody explain this behavior?


Solution 1:

C99 requires that when a/b is representable:

(a/b) * b + a%b shall equal a

This makes sense, logically. Right?

Let's see what this leads to:


Example A. 5/(-3) is -1

=> (-1) * (-3) + 5%(-3) = 5

This can only happen if 5%(-3) is 2.


Example B. (-5)/3 is -1

=> (-1) * 3 + (-5)%3 = -5

This can only happen if (-5)%3 is -2

Solution 2:

The % operator in C is not the modulo operator but the remainder operator.

Modulo and remainder operators differ with respect to negative values.

With a remainder operator, the sign of the result is the same as the sign of the dividend (numerator) while with a modulo operator the sign of the result is the same as the divisor (denominator).

C defines the % operation for a % b as:

  a == (a / b * b) + a % b

with / the integer division with truncation towards 0. That's the truncation that is done towards 0 (and not towards negative inifinity) that defines the % as a remainder operator rather than a modulo operator.

Solution 3:

Based on the C99 Specification: a == (a / b) * b + a % b

We can write a function to calculate (a % b) == a - (a / b) * b!

int remainder(int a, int b)
{
    return a - (a / b) * b;
}

For modulo operation, we can have the following function (assuming b > 0)

int mod(int a, int b)
{
    int r = a % b;
    return r < 0 ? r + b : r;
}

My conclusion is that a % b in C is a remainder operation and NOT a modulo operation.

Solution 4:

I don't think there isn't any need to check if the number is negative.

A simple function to find the positive modulo would be this -

Edit: Assuming N > 0 and N + N - 1 <= INT_MAX

int modulo(int x,int N){
    return (x % N + N) %N;
}

This will work for both positive and negative values of x.

Original P.S: also as pointed out by @chux, If your x and N may reach something like INT_MAX-1 and INT_MAX respectively, just replace int with long long int.

And If they are crossing limits of long long as well (i.e. near LLONG_MAX), then you shall handle positive and negative cases separately as described in other answers here.

Solution 5:

The other answers have explained in C99 or later, division of integers involving negative operands always truncate towards zero.

Note that, in C89, whether the result round upward or downward is implementation-defined. Because (a/b) * b + a%b equals a in all standards, the result of % involving negative operands is also implementation-defined in C89.