Why does C++ output negative numbers when using modulo?

Martin Thoma picture Martin Thoma · Jul 24, 2012 · Viewed 24.4k times · Source

Math:

If you have an equation like this:

x = 3 mod 7

x could be ... -4, 3, 10, 17, ..., or more generally:

x = 3 + k * 7

where k can be any integer. I don't know of a modulo operation is defined for math, but the factor ring certainly is.

Python:

In Python, you will always get non-negative values when you use % with a positive m:

#!/usr/bin/python
# -*- coding: utf-8 -*-

m = 7

for i in xrange(-8, 10 + 1):
    print(i % 7)

Results in:

6    0    1    2    3    4    5    6    0    1    2    3    4    5    6    0    1    2    3

C++:

#include <iostream>

using namespace std;

int main(){
    int m = 7;

    for(int i=-8; i <= 10; i++) {
        cout << (i % m) << endl;
    }

    return 0;
}

Will output:

-1    0    -6    -5    -4    -3    -2    -1    0    1    2    3    4    5    6    0    1    2    3    

ISO/IEC 14882:2003(E) - 5.6 Multiplicative operators:

The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined 74).

and

74) According to work underway toward the revision of ISO C, the preferred algorithm for integer division follows the rules defined in the ISO Fortran standard, ISO/IEC 1539:1991, in which the quotient is always rounded toward zero.

Source: ISO/IEC 14882:2003(E)

(I couldn't find a free version of ISO/IEC 1539:1991. Does anybody know where to get it from?)

The operation seems to be defined like this:

enter image description here

Question:

Does it make sense to define it like that?

What are arguments for this specification? Is there a place where the people who create such standards discuss about it? Where I can read something about the reasons why they decided to make it this way?

Most of the time when I use modulo, I want to access elements of a datastructure. In this case, I have to make sure that mod returns a non-negative value. So, for this case, it would be good of mod always returned a non-negative value. (Another usage is the Euclidean algorithm. As you could make both numbers positive before using this algorithm, the sign of modulo would matter.)

Additional material:

See Wikipedia for a long list of what modulo does in different languages.

Answer

ecatmur picture ecatmur · Jul 24, 2012

On x86 (and other processor architectures), integer division and modulo are carried out by a single operation, idiv (div for unsigned values), which produces both quotient and remainder (for word-sized arguments, in AX and DX respectively). This is used in the C library function divmod, which can be optimised by the compiler to a single instruction!

Integer division respects two rules:

  • Non-integer quotients are rounded towards zero; and
  • the equation dividend = quotient*divisor + remainder is satisfied by the results.

Accordingly, when dividing a negative number by a positive number, the quotient will be negative (or zero).

So this behaviour can be seen as the result of a chain of local decisions:

  • Processor instruction set design optimises for the common case (division) over the less common case (modulo);
  • Consistency (rounding towards zero, and respecting the division equation) is preferred over mathematical correctness;
  • C prefers efficiency and simplicitly (especially given the tendency to view C as a "high level assembler"); and
  • C++ prefers compatibility with C.