Deep JavaScript

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:

• The remainder operator `rem`
• The modulo operator `mod`

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:

• With `rem`, the result has the same sign as the dividend (first operand):

``````> 5 rem 4
1
> -5 rem 4
-1
> 5 rem -4
1
> -5 rem -4
-1``````
• With `mod`, the result has the same sign as the divisor (second operand):

``````> 5 mod 4
1
> -5 mod 4
3
> 5 mod -4
-3
> -5 mod -4
-1``````

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:

• `-2 rem 3 = -2`
3 × 0 gets us close to −2. The difference between 0 and the dividend −2 is −2.

• `-2 mod 3 = 1`
3 × −1 also gets us close to −2. The difference between −3 and the dividend −2 is 1.

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

• `2 rem -3 = 2`
-3 × 0 gets us close to 2.

• `2 mod -3 = -1`
-3 × -1 gets us close to 2.

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:

• To convert the operands of the `>>>` operator to unsigned 32-bit integers (`x mod 2**32`):

``````> 2**32 >>> 0
0
> (2**32)+1 >>> 0
1
> (-1 >>> 0) === (2**32)-1
true``````
• To convert arbitrary numbers so that they fit into Typed Arrays. For example, `x mod 2**8` is used to convert numbers to unsigned 8-bit integers (after first converting them to integers):

``````const tarr = new Uint8Array(1);

tarr[0] = 256;
assert.equal(tarr[0], 0);

tarr[0] = 257;
assert.equal(tarr[0], 1);``````