Modulo…It’s All You’re Left With. And Other Tales From a Divided World.

There will be times in your development career when you will either need to find how many times an integer is divisible by another integer, or you will need to know how much is left over after that division. Fortunately, Ruby has several built-in methods to help you find the quotient, the remainder, both, or neither. Unfortunately, Ruby has several built-in methods to help you find the quotient, the remainder, both, or neither. In certain situations, they actually return different results. In this article, I’m going to attempt to clarify how each works and in what situations you would want to use each of them.

Let’s begin my looking at this chart I grabbed off of the ruby-lang.org site: (https://docs.ruby-lang.org/en/2.6.0/Numeric.html#method-i-divmod)

 a    |  b  |  a.divmod(b)  |  a/b    | a.modulo(b) | a.remainder(b)
------+-----+---------------+---------+-------------+---------------
13 | 4 | 3, 1 | 3 | 1 | 1
------+-----+---------------+---------+-------------+---------------
13 | -4 | -4, -3 | -4 | -3 | 1
------+-----+---------------+---------+-------------+---------------
-13 | 4 | -4, 3 | -4 | 3 | -1
------+-----+---------------+---------+-------------+---------------
-13 | -4 | 3, -1 | 3 | -1 | -1

In the first two columns, you will find the dividend (a) and the divisor (b) — we will be dividing the dividend by the divisor: dividend / divisor. In the next column, you see the results from calling the Numeric#divmod method, which returns an array with both the quotient (the whole number result of performing division) and the Integer#modulo(mod, or just %), the signed remainder after the division operation is complete. The next two columns show the return values from the individual division and mod operations, respectively. The last column shows the result of the Integer#remainder method. As you can see, sometimes modulo and remainder return the same results, but sometimes the results are very different. What you are looking for in the end will determine which method you will use. From now on, assume that all the numbers in the examples are integers.

Division

Let’s start out with an easy problem. Say you want to find out how many times 4 goes into 13. That’s easy, you just use Ruby’s Integer#/ method, and you’re done. Remember, the result will be positive if both numbers are either + or -, and negative if only one of the numbers is -.

> 13 / 4
=> 3
> -13 / 4
=> -4

In Ruby, when you perform integer division, it only returns the whole number quotient and not the remainder. If you want the remainder, Ruby comes with a couple handy methods: Integer#remainder and Integer#%, that works like this:

> 13.remainder(4)
=> 1
> -13.remainder(-4)
=> -1
> 13 % 4
=> 1
> -13 % -4
=> -1

Which is saying that when you divide 13, 4 times, you have 1 leftover; or -13, -4 times, you have -1 left over. Pretty easy to understand, yes? Both methods will return the same value, if both numbers, a and b, share the same sign — a positive return value if both a and b are positive, or a negative return value if both a and b are negative. Where it gets tricky is when a and b are different signs. The key to understanding which method to use, at which time, is understanding how each method arrives at its particular result.

#remainder

When you use Ruby’s Integer#remainder method, you are really performing division with the absolute values of a and b (the absolute value of a number is the number without a sign, i.e.|-1| = 1), with the result being the remainder and taking the sign of the dividend:

> |13|/|4|
=> 1
> 13.remainder(4)
=> 1
> |-13|/|4|
=> -1
> -13.remainder(4)
=> -1

Which is why you will always get the same answer, with just the signs differing. This is useful when you need to find the remainder of performing division.

#modulo

Modulo (pronounced mod-you-low), or mod, is more common to most developers than #remainder. It is typically used to find if one number evenly divides into another number.

> 2 % 2 == 0
=> true
> 3 % 2 == 0
=> false

The above code will tell you whether a number is even (top) or odd (bottom). Where mod gets confusing, is when you deal with negative numbers. When one of the numbers is negative, modulo returns the actual distance on the number line that you have to go to get from the quotient to the dividend.

> -13 % 4
=> 3
> -13 / 4
=> -4
> -4 * 4
=> -16
Distance from -13 to -16 is 3, the modulus

As you can see, mod works significantly different from #remainder when dealing with negative numbers.

#divmod

When you need to find both the quotient and the modulus, Ruby has a method that will return both at the same time — Numeric#divmod.

> 13.divmod(4)
=> [3, 1]
> quotient, remainder = 13.divmod(4)
> quotient
=> 3
> remainder
=> 1

As you can see, #divmod returns an array with index 0 containing the quotient and index 1 containing the modulus. I’ve included a little trick if you want the results to go into specific variables.

So what use does mod have besides determining whether a number is odd or even? What if you had an array and wanted to select every nth element (e.g. every 3rd element, starting with the element index 2)?

def find_every_nth_ele(arr, start_idx, nth)
arr.select.with_index { |ele, idx| ele if idx % nth == start_idx } end
# find every 3rd element starting with index 2
# i.e. the value at index 5, 8, 11, 14
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]> find_every_nth_ele(array, 2, 3)
=> [3, 6, 9, 12, 15]

In the above example, we are looking for every 3rd element, starting with the element at index 2. Mod allows us to accomplish this because it returns the remainder, which is the same as the index we want to start at and count from. An example might help with the explanation:

# When idx is 2, which is the first index we want to select
> 2 % 3 == 2
=> true # 2 % 3 returns 2
# this is because 3 goes into 2 zero times, with 2 remaining
# When idx is 5, which is the second index we want to select
> 5 % 3 == 2
=> true # 5 % 3 returns 2
# this is because 3 goes into 5 one time, with 2 remaining

Using mod and start_idx allowed us to check if an index is 2 more than what it would be if we were counting from the actual starting index of 0, allowing us to start the selection at idx 2 and selecting every third element. This works for any starting index (except 0 — returns a ZeroDivisionError) and any size of increments.

I hope you have a better understanding of the power of #modulo and #remainder and how you can use them in your career as a software developer.

More reading

If you’d like to read more, here are a couple of pages I found helpful:

Baker turned software engineering student.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store