When would it be useful to use the modulus operator (fmod() or %)?

I’ve been using roblox studio a lot lately and it’s helped me understand a lot of mathematical and programming concepts that I’m being taught in class.

A really big topic I’m currently having trouble relating to is the modulus operator. It’s being used all throughout my course and is especially important for some proofs I need to know.

I was wondering if anybody had experience using it and could explain some pretty neat situations where it’d be useful. This’d really help me understand not only more about roblox studio but my course material too! (I’ve got finals coming up and I’m struggling :smiling_face_with_tear:)

Hello! I don’t know all the uses for the mod operator, but one can use it to determine whether a number is even or odd. For example, if you have NumberA and you don’t know what it is but want to determine whether it is even or odd, you can put

if NumberA % 2 == 0 then
     print("NumberA is an even number")
else
     print("NumberA is an odd number")
end 


2 Likes

Mod is super useful for creating UI effects like when a player list has every other line darker or sorting through stuff like a player list to assign every other player to a certain team etc.

1 Like

Hey, I found it useful when creating a grid placement functionality, as in a “snap to grid” building feature that many games have out there. Having an asset you want placed into the environment via the player’s mouse position can create unwanted freedom for the player, imagine if in Minecraft you could place blocks hanging off others, or a few pixels offset from the block you’re placing it on, it creates problems. I found that using (mouse position - (mouse position%5)) for example was an efficient way to snap whatever the player is building to a 5 by 5 grid.

local ObjectCFrame = CFrame.new((Mouse.Hit.Position.X) - (Mouse.Hit.Position.X%5), 
PreviewObject.PrimaryPart.Size.Y/2, (Mouse.Hit.Position.Z) - (Mouse.Hit.Position.Z%5))

This for example, is the bit of code I used to snap the preview of the to-be placed object to a 5x5 grid. Not sure how helpful this was to your question, but I thought it was a neat use of the mod operator.

2 Likes

Wow thats actually great! I’ll remember that for later, thanks alot!

2 Likes

Sorry for the late response, finals have been KILLING me. But thank you so much for this, I’ll definitely be giving this a try and see what other things I figure out.

2 Likes

Think grade-school long-division problems, before we learned about decimals. That’s a straight-forward way to think about it. The mod is just the remainder.

   __0_r0        __0_r1        __0_r2        __0_r3        __0_r4
5 )  0        5 )  1        5 )  2        5 )  3        5 )  4

   __1_r0        __1_r1        __1_r2        __1_r3        __1_r4
5 )  5        5 )  6        5 )  7        5 )  8        5 )  9

   __2_r0        __2_r1        __2_r2        __2_r3        __2_r4
5 ) 10        5 ) 11        5 ) 12        5 ) 13        5 ) 14

   __3_r0        __3_r1        __3_r2        __3_r3        __3_r4
5 ) 15        5 ) 16        5 ) 17        5 ) 18        5 ) 19

Since we are dividing by 5 here, the possible integer remainders will be the 5 values in the range 0-4 (or 0 to n-1). Mentally, you might think of mod as a sort of division where you use ‘%’ instead of ‘/’ and the result is the remainder rather than the quotient.

0 % 5 = 0     1 % 5 = 1     2 % 5 = 2     3 % 5 = 3     4 % 5 = 4   
5 % 5 = 0     6 % 5 = 1     7 % 5 = 2     8 % 5 = 3     9 % 5 = 4
10 % 5 = 0     etc

If we think of the equation as x % n = r, it has the useful property of assigning to r the result of wrapping any value x we give it into the range [0, n)<-up to not inclu n. This modular arithmetic is also called clock arithmetic because as you go around the clock adding numbers you reach a point at 12 where it loops. The hour hand on a clock is mod 12, though you’d prob want to interpret the 0 as a 12 in a clock app since that’s the convention (the second hand is mod 60, so values from 0 to 59).

Beyond just finding a remainder, it’s this looping or wrapping feature of mod that makes it most useful for programming. If you are dealing with rotations and want your values to stay in the range [0, 360), then you can use angle = angle % 360 to convert any rotation value to its corresponding angle within that range. Periodic functions like those from trig can be likewise constrained. Anytime you have a counter that you’d like to let grow and grow but would really like all the values to represent a position within a fixed range, you can use mod to do that. If you converted a 2D array, like an image, into a 1D array, you could still find the entry that corresponded to a given (x,y) coord by using mod (x = index % width and y = math.floor(index / width)).

Mod can work with decimals as the x part (wouldn’t use decimals for n even if it’s supported), so you could wrap values like 780.25 % 360 = 60.25 (degrees). Negative numbers can be used for things like wrapping circular buffers using positive or negative indices or wrapping negative screen or world coords if you need to use negative positions.

Applications for mod can be found from actual clock implementations to wrapping screen coords to hash functions, data validation, cryptography, and more, wherever data is worked with in a cyclical manner.

1 Like

The idea of “looping” with it is something I never even thought about it, thank you so much for responding with all of this. I’m already learning so much thanks to you guys!

1 Like

That’s mostly what I’ve used it for. The looping idea can help with understanding how negative values, decimals, and even decimals for the modulo fit in conceptually. Yes, it’s all just remainders, but it can be tricky to understand what that means exactly for negatives or for something like (10 % 2.5).

I used a can and a flexible cloth tape measure to explain it to my daughter when she was first introduced to the idea. We wrapped the tape around the can and marked off units with a sharpie. She could then wrap the tape around as many times as she wanted and could see how all the subsequent wraps corresponded to the earlier markings.

Wrapping the tape in the opposite direction illustrated the idea of negative values. For example, on a clock if you start at 12 and go CCW one spot, or -1, you get 11. It turns out that -1 % 12 = 11.

It also turned out that the circumference of our can was not a nice round number, so as she looped the tape the numbers seemed to fall in a strange way because they weren’t nice round multiples. This non-integer circumference was basically like using a decimal for the mod. If you imagine a pipe that has a 12.8 inch circumference (instead of a nice even 12), if you wrap a long cord around it eventually you will run out of cord and it will end with a remainder somewhere between 0 and 12.8 inches. So in x % n = r the n is like the circumference of some cylinder and the x is the length of cord you wrap around it a bunch of times. The r tells you how much cord you end up with that didn’t make a complete wrap, and it will be somewhere between 0 and whatever the circumference of the cylinder was—no matter how much or how little cord you started with.—or which direction you wrapped it. Finding places to use mod is equivalent to finding cylinders with circumferences that matter to your task. 12 or 24 for hrs, 60 for min, 365 for days, 360 for degrees, the width of your screen or an image, the period of a fn.

Anyway, having some kind of a mental model of how it works can help when you want to sort out what it’s doing in code you come across. I’ll generally visualize it as either a circle, like the clock, or as an array of little boxes in a line that should wrap back to the beginning when it reaches the end, or as a section of a sine wave from 0 to 2*pi, for example. When you see it in an algorithm or in someone else’s code it’s almost always going to be related to that idea of wrapping values into a range, so you’re usually safe with that as your initial assumption.

1 Like