23

Today at work I had an interesting discussion with one of my coworkers. He was surprised when he had the following happen to him:

assert(-1 % 10 == -1)  //Expecting 9

So when he came to ask me about it, I told him "well, that makes sense. When you divide -1 by 10, you get 0 with -1 remaining. His argument however was that the modulus operator is supposed to hold true to the "always positive" model. I did a little research and found that the modulus he was referring to looks like this:

Let q be the integer quotient of a and n. Let r be the remainder. Then:

a = n * q + r

The definition I was using, however, appears to be the Knuth version of modulus, which is:

Let q be the floor of a divided by n. Let r be the remainder. Then:

r = a - n * q

So, my question is why it ended up in the FORTRAN standard (and subsequently the C-standard) to have the modulus operator truncate toward 0? It seems like a misnomer to me to call it "modulus" and not "remainder" (In math, the answer really should be 9). Is this related to how hardware is doing the division?

For reference:

TLDR; Is hardware the reason the modulus operator truncates toward 0?

Community
  • 1
  • 1
Chad La Guardia
  • 5,088
  • 4
  • 24
  • 35
  • 3
    You do realize that this question and the links are full of reasons to avoid modulo with negative operands? – H H Feb 14 '12 at 21:50
  • 5
    Avoiding it is not the point of the question. – Chad La Guardia Feb 14 '12 at 22:11
  • Is it really called "modulus" or "mod"? How many syllables does "mod" have? How about "remainder"? – supercat Jun 19 '13 at 21:51
  • 1
    @supercat "modulus" and "remainder" each have 3 syllables. "mod" and "rem" each have 1 syllable. – OJFord Sep 26 '14 at 18:44
  • 1
    @OllieFord: "REM" is a keyword in BASIC, and probably some BASIC-derived languages as well, which serves to introduce a comment. Additionally, some languages use "%" to introduce comments. Thus, describing "%" as the "rem" operator might cause some confusion. – supercat Sep 26 '14 at 19:01

3 Answers3

17

It seems like a misnomer to me to call it "modulus" and not "remainder" (In math, the answer really should be 9).

C calls it the % operator, and calls its result the remainder. C++ copies this from C. Neither language calls it the modulus operator. This also explains why the remainder is negative: because the / operator truncates towards 0, and (a / b) * b + (a % b) should equal a.

Edit: David Rodríguez rightly points out that C++ does define a template class std::modulus, which calls operator%. In my opinion, that class is poorly named. Digging a little bit, it is inherited from STL where it was already named as it is now. The download for STL says "The STL was developed on SGI MIPSproTM C++ 7.0, 7.1, 7.2, and 7.2.1.", and as far as I can tell without actually having the compiler and hardware, MIPSpro passes the division to the CPU and MIPS hardware truncates to 0, which would mean std::modulus has always been misnamed.

  • 2
    +1 I just checked the C++ standard: *the binary % operator yields the remainder from the division of the first expression by the second*, so +1 for the operator itself. Now another issue is the name of the functor in `functional` that uses `operator%` which is called *modulus*, so at least part of the question is left open... – David Rodríguez - dribeas Feb 14 '12 at 21:56
  • @DavidRodríguez-dribeas Nice find, I cannot answer on the history behind that and why it is named as it is. –  Feb 14 '12 at 22:02
  • 1
    I think the source of confusion, for me at least, is that if you use `fmod`, for example, you will not get a true modulus, as the name would imply. It seems as if the two words are used interchangebly. But you are correct, the true C++ standard does say remainder. The original source I used was MSDN because I was looking specifically for VS2003. http://msdn.microsoft.com/en-us/library/ty2ax9z9(v=vs.71).aspx. It would appear that they are incorrect. – Chad La Guardia Feb 14 '12 at 22:10
  • 1
    @ChadLaGuardia Also a good example of a misnamed function of which the return value is not fully specified. C and C++ have since addressed that by adding a more reliable `remainder` function, but I don't think VS2003 has it. –  Feb 14 '12 at 22:20
5

% is the remainder operator in C and C++.

In the C++ Standard, it is called the %operator and it yields the the remainder from the division. In the C Standard it is called the % operator and since C99 it is actually a remainder operator. The modulo and remainder operators differ with respect to negative values.

The % operator is defined in C and C++ with a == (a / b * b) + a % b.

Truncation of the integer division towards 0 in C is done since C99. In C89 it was implementation defined (and % can be a modulo operator in C89). C++ also performs truncation towards zero for integer division.

When truncation is done towards zero, % is a remainder operator and the sign of the result is the sign of the dividend. When truncation is done towards minus infinity, % is a modulo operator and the sign of the result is the sign of the divisor.

On the reasons why C changed the implementation defined behavior of the integer division regarding truncation, Doug Gwyn from C comittee said:

C99 imposed a Fortran-compatible requirement in an attempt to attract more Fortran rogrammers and to aid in converting Fortran code to C.

C99 Rationale says regarding truncation towards zero integer division:

In Fortran, however, the result will always truncate toward zero, and the overhead seems to be acceptable to the numeric programming community. Therefore, C99 now requires similar behavior, which should facilitate porting of code from Fortran to C.

In gcc the implementation behavior in C89 has always been the truncation towards zero.

So % is the remainder operator in C99, C++ and also in Java but is not the remainder operator in all programming languages. In Ruby and Python, % is in fact the modulo operator (integer division is done towards minus infinity in these languages). Haskhell and Scheme have two separate operators: mod and rem for Haskell, and modulo and remainder for Scheme.

ouah
  • 142,963
  • 15
  • 272
  • 331
1

I'm afraid that the problem arises from a misunderstanding of mathematics. Congruence modulo n is an equivalence relation, so it only defines equivalence classes. Hence, it's not correct to say that 'in math, the answer really should be 9' because it could be as well 19, 29, and so forth. And of course it can be -1 or -11. There are infinite elements of the class of the numbers n that are n ≡ -1 mod(10).

http://en.wikipedia.org/wiki/Modular_arithmetic

http://en.wikipedia.org/wiki/Congruence_relation

So, the correct question could be: which element of the class of the numbers that are ≡ -1 mod(10) will be the result of -1 % 10 in C++? And the answer is: the remainder of the division of -1 by 10. No mystery.

PS Your definition of modulus and Knuth's are, ehm, equivalent...:)

ascanio
  • 1,506
  • 1
  • 9
  • 18
  • Those definitions are not equal. Plug in -1 % 10 and you will see why. – Chad La Guardia Feb 14 '12 at 22:35
  • Why? "Let q be the integer quotient of a and n" it's the same of "Let q be the floor of a divided by n". The rest of the definition is perfectly equal, given that you flip n*q on the other side of the equal...;) – ascanio Feb 14 '12 at 22:42
  • 3
    Many people would expect that the % operation would return a unique representative of the equivalence class. This is not the case, because it returns different representatives for pairs of integers that belong to the same equivalence class (x and -x, x!=0). Your argument that -1%10 could be -1 or -11 would only make sense if the same offset from [0, m-1] was always used (e.g. if -1%10=-11, then 9%10 should too be -11 and not 9). – Ambroz Bizjak Feb 14 '12 at 22:59
  • I don't understand what you're saying...I was talking about mathematics first, then about the C++ language and its real behaviour. In the real world C++, I'm pretty sure that % operator yields *one* result for one input (otherwise it would be non-deterministic..) but in mathematics they are all valid in principle. I believe that this is the typical case in which a doubt about a real-world programming language arise from a bad understanding of a mathematical concept. In this case the assumption that -1 % 10 should be 9 is simply wrong. – ascanio Feb 15 '12 at 00:02
  • 1
    I'm not saying that there's anything wrong about the way % is defined in C/C++. I'm just saying that the expectation to consistently return values from [0, m-1] has a mathematical basis. To re-iterate: many people would expect that the % operation would return a unique representative of the equivalence class. (and many would expect it to behave exactly how it does) – Ambroz Bizjak Feb 15 '12 at 00:34
  • 2
    @AmbrozBizjak: In other words, from a mathematical standpoint, the statement `(x % b)==(y % b)` should be true when, and only when, x and y are in the same equivalence class mod b. A language could e.g. define the `%` operator to assume rounded division (in which case the sign of the result would indicate how the the dividend should be adjusted to reach an exact multiple of the divisor) and meet that expectation, but the operator implemented in C does not. – supercat Dec 19 '13 at 21:38