Remainder operator vs. modulo operator (with JavaScript code)

Originally published at https://2ality.com

Overview: Two operators  

Let’s assume there are two operators that are very similar:

  • The remainder operator rem
  • The modulo operator mod

If both operands have the same signs, then the operators produce the same results:

> 5 rem 3
2
> 5 mod 3
2

> -5 rem -3
-2
> -5 mod -3
-2

If, however, they have different signs, then the result of rem has the same sign as the first operand, while the result of mod has the same sign as the second operand:

> -5 rem 3
-2
> -5 mod 3
1

> 5 rem -3
2
> 5 mod -3
-1

Why is that? Read on.

The remainder operator rem  

We’ll first take a closer look at the rem operator:

dividend rem divisor

In order to compute the remainder, we use the following two equations:

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

dividend, divisor, quotient, and remainder are all integers (for the sake of this blog post).

In order to compute the remainder we must find the quotient:

remainder = dividend - divisor * quotient

And we do so by dividing the dividend by the divisor. Math.trunc() ensures that the resulting quotient is an integer.

Example 1: 5 rem 3 === 2

const dividend = 5;
const divisor = 3;
const quotient = Math.trunc(dividend / divisor);
assert.equal(quotient, 1);

Example 2: -5 rem 3 === -2

const dividend = -5;
const divisor = 3;
const quotient = Math.trunc(dividend / divisor);
assert.equal(quotient, -1);

The modulo operator mod  

The modulo operator is based on the same equations, but it uses Math.floor() to compute quotients:

  • If both dividend and divisor are positive, the modulo operator produces the same results as the remainder operator (example 3).
  • If, however, dividend and divisor have different signs, then the results are different (example 4).

The reason for that is that Math.trunc() and Math.floor() produce the same results for positive numbers, but different results for negative numbers.

Example 3: 5 mod 3 === 2 (dividend is 5, divisor is 3)

const dividend = 5;
const divisor = 3;
const quotient = Math.floor(dividend / divisor);
assert.equal(quotient, 1);

Example 4: -5 mod 3 === 1 (dividend is −5, divisor is 3)

const dividend = -5;
const divisor = 3;
const quotient = Math.floor(dividend / divisor);
assert.equal(quotient, -2);

An intuitive explanation of modulo  

Modulo can also be viewed as an operation that maps an arbitrary number into a given range – for example:

x mod 3

maps x into the range

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

That is, zero is included, 3 is excluded.

If x is already inside the range, performing the mapping is simple:

> 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:

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

This is how the mapping is extended so that it also covers negative integers:

-7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
2 0 1 2 0 1 2 0 1 2 0 1 2 0 1
> -1 mod 3
2
> -3 mod 3
0
> -4 mod 3
2

x rem 3 maps x as follows:

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

Negative right-hand side  

x mod -3 maps x to the range (-3, 0]

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

x rem -3 has the following mapping (the same as x rem 3):

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

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 (via x mod 232):

·        > 232 >>> 0
·        0
·        > (232)+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);

Conclusions and further reading  

Which of rem and mod is supported and how depends on the programming language:

  • JavaScript‘s % operator is a remainder operator.
  • Python’s % operator is a modulo operator.

If you want to read more about remainder and modulo:

Thanks for reading

If you liked this post, please do share/like it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about JavaScript

The Complete JavaScript Course 2019: Build Real Projects!

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

JavaScript Bootcamp - Build Real World Applications

The Web Developer Bootcamp

JavaScript Programming Tutorial - Full JavaScript Course for Beginners

New ES2019 Features Every JavaScript Developer Should Know

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

React vs Angular vs Vue.js by Example

Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)

Creating Web Animations with Anime.js

Ember.js vs Vue.js - Which is JavaScript Framework Works Better for You

Do we still need JavaScript frameworks?


#javascript #web-development

Remainder operator vs. modulo operator (with JavaScript code)
13.65 GEEK