5.5 The equations behind remainder and modulo

The following two equations define both remainder and modulo:

  1. dividend = (divisor * quotient) + remainder
  2. |remainder| < |divisor|

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

  1. remainder = dividend - (divisor * quotient)
  2. 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():

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

5.5.3 Implementing mod

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

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

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.