Deep JavaScript
Please support this book: buy it or donate
(Ad, please don’t block.)

5 % is a remainder operator, not a modulo operator



Remainder and modulo are two similar operations. This chapter explores how they work and reveals that JavaScript’s % operator computes the remainder, not the modulus.

5.1 Remainder operator rem vs. modulo operator mod

In this chapter, we pretend that JavaScript has the following two operators:

That will help us examine how the underlying operations work.

5.2 An intuitive understanding of the remainder operation

The operands of the remainder operator are called dividend and divisor:

remainder = dividend rem divisor

How is the result computed? Consider the following expression:

7 rem 3

We remove 3 from the dividend until we are left with a value that is smaller than 3:

7 rem 3 = 4 rem 3 = 1 rem 3 = 1

What do we do if the dividend is negative?

-7 rem 3

This time, we add 3 to the dividend until we have a value that is smaller than -3:

-7 rem 3 = -4 rem 3 = -1 rem 3 = -1

It is insightful to map out the results for a fixed divisor:

x:       -7 -6 -5 -4 -3 -2 -1  0  1  2  3  4  5  6  7
x rem 3: -1  0 -2 -1  0 -2 -1  0  1  2  0  1  2  0  1

Among the results, we can see a symmetry: x and -x produce the same results, but with opposite signs.

5.3 An intuitive understanding of the modulo operation

Once again, the operands are called dividend and divisor (hinting at how similar rem and mod are):

modulus = dividend mod divisor

Consider the following example:

x mod 3

This operation maps x into the range:

[0,3) = {0,1,2}

That is, zero is included (opening square bracket), 3 is excluded (closing parenthesis).

How does mod perform this mapping? It is easy if x is already inside the range:

> 0 mod 3
0
> 2 mod 3
2

If x is greater than or equal to the upper boundary of the range, then the upper boundary is subtracted from x until it fits into the range:

> 4 mod 3
1
> 7 mod 3
1

That means we are getting the following mapping for non-negative integers:

x:       0 1 2 3 4 5 6 7
x mod 3: 0 1 2 0 1 2 0 1

This mapping is extended as follows, so that it includes negative integers:

x:       -7 -6 -5 -4 -3 -2 -1  0  1  2  3  4  5  6  7
x mod 3:  2  0  1  2  0  1  2  0  1  2  0  1  2  0  1

Note how the range [0,3) is repeated over and over again.

5.4 Similarities and differences between rem and mod

rem and mod are quite similar – they only differ if dividend and divisor have different signs:

5.5 The equations behind remainder and modulo

The following two equations define both remainder and modulo:

dividend = (divisor * quotient) + remainder
|remainder| < |divisor|

Given a dividend and a divisor, how do we compute remainder and modulus?

remainder = dividend - (divisor * quotient)
quotient = dividend div divisor

The div operator performs integer division.

5.5.1 rem and mod perform integer division differently

How can these equations contain the solution for both operations? If variable remainder isn’t zero, the equations always allow two values for it: one positive, the other one negative. To see why, we turn to the question we are asking when determining the quotient:

How often do we need to multiply the divisor to get as close to the dividend as possible?

For example, that gives us two different results for dividend −2 and divisor 3:

It also gives us two different results for dividend 2 and divisor −3:

The results differ depending on how the integer division div is implemented.

5.5.2 Implementing rem

The following JavaScript function implements the rem operator. It performs integer division by performing floating point division and rounding the result to an integer via Math.trunc():

function rem(dividend, divisor) {
  const quotient = Math.trunc(dividend / divisor);
  return dividend - (divisor * quotient);
}

5.5.3 Implementing mod

The following function implements the mod operator. This time, integer division is based on Math.floor():

function mod(dividend, divisor) {
  const quotient = Math.floor(dividend / divisor);
  return dividend - (divisor * quotient);
}

Note that other ways of doing integer division are possible (e.g. based on Math.ceil() or Math.round()). That means that there are more operations that are similar to rem and mod.

5.6 Where are rem and mod used in programming languages?

5.6.1 JavaScript’s % operator computes the remainder

For example (Node.js REPL):

> 7 % 6
1
> -7 % 6
-1

5.6.2 Python’s % operator computes the modulus

For example (Python REPL):

>>> 7 % 6
1
>>> -7 % 6
5

5.6.3 Uses of the modulo operation in JavaScript

The ECMAScript specification uses modulo several times – for example:

5.7 Further reading and sources of this chapter