[Tutorial] Modulo Operator
#1

Modulo Operator in Pawn



Preface
I'd like to begin to say that this is not an ordinary pawn scripting tutorial. This is a simple tutorial covering the modulo operator. When I searched on the forums with the word "modulo" on thread search I only found three threads where one was a tutorial in Portuguese, and two where "help me" threads so I decided to write this, even though if you guys find it bad, I tried my best to explain with my own words and with my knowledge from last semesters "Discrete Mathematics". This tutorial will most be math but "format" might show up.

Skip to next title to get to know how to use modulo in pawn language.



Mod what?
Modulo is an operator in most scripting languages and in mathematics just like addition (+), subtraction (-), multiplication (*) or other operators. They all have different functions. The modulo operator gives us the so called "rest" from a division. In the world we live in, we have no modulo. That is although wrong, we do have a mod but it's infinity. This is where it begins to struggle with most people. The mod tells us when to stop counting and start back again from 0.

Let's jump into some examples before it gets too annoying:
Code:
11 mod 6 ≡ 5
12 mod 6 ≡ 0
13 mod 6 ≡ 1
Figure 1
Wait wait what did just happen? Well let me explain before you go and report me to SA-MP for bad tutorial: When you use modulo you are dividing the number in front of the word "mod" with the number after "mod".
Code:
11/6 = 1,8333333333333333333333333333333
12/6 = 2
13/6 = 2,1666666666666666666666666666667
Figure 2
But that is not the what you wrote above? Why not? Because division and modulo are two different things but modulo wouldn't be explainable without division so I am using this method to explain modulo. To continue, what you do is that you use the fractional part to calculate the rest. Now you're asking what a fractional part is, look below:
Code:
Fractional part examples:
0.5 = Fractional part is 0.5
1.2 = Fractional part is 0.2 
5.852 = Fractional part is 0.852
1000000.52 = Fractional part is 0.52
Figure 3
It is everything after the comma sign. If you have larger numbers you will have to multiply the "fractional part" with the modulo number after removing anything to the left of the comma sign and then you will have the rest.
Code:
11/6 = 1,8333333333333333333333333333333
1,8333333333333333333333333333333 - 1 = 0,8333333333333333333333333333333
0,8333333333333333333333333333333 * 6 = 5 (rounded)
Answer: 11 mod 6 ≡ 5

12/6 = 2
2 - 2 = 0
0 * 6 = 0
Answer: 12 mod 6 ≡ 0

13/6 = 2,1666666666666666666666666666667
2,1666666666666666666666666666667 - 2 = 0,1666666666666666666666666666667
0,1666666666666666666666666666667 * 6 = 1
Answer: 12 mod 6 ≡ 1
Figure 4
"Oh okay now I understand that, but what is ≡?" Well that is just like equals sign (=) but when using modulo. More important when using in written language than in computer languages because you won't need that sign ever as far as I know. The actual meaning of it is, according to my high school physics teacher (that by the way was from Oxford, yes very much brag in this tutorial!), means that is it even stronger equals than normal equals. Enough with bragging.

What happens when you use it?
A bit more explained it counts basically like this:
Code:
You have "12 mod 6" as an example:
Our counting | modulo counting
0  | 0
1  | 1
2  | 2
3  | 3
4  | 4
5  | 5
6  | 0
7  | 1
8  | 2
9  | 3
10 | 4
11 | 5
12 | 0
Figure 5
Let's say you ever struggle with high amounts and want to calculate the modulo and you don't have a calculator who can calculate modulo, then the way of calculating above (figure 4) is better than writing what I wrote above here in Figure 5. Now all this was just to give an idea of what modulo actually is for those who are interested of knowing a bit more about it, and there are other methods to calculate it, I know, but just to explain one of them, I chose this one.



Pawn modulo
To use this "complicated" operator in pawn language we use the operator sign "%". Many languages uses this such as C#. To my previous examples, it would be written like this:
Code:
Previous: 12 mod 6
Pawn: 12 % 6
Simple right? Well I hope you feel that it is simple. You just change the word "mod" to "%". As taken from the preface where I stated that I searched for "modulo" on the SA-MP forums, I did not find very much. And I see the reason why, you don't use this many times but I have seen now two times in a week that people ask about getting minutes into seconds in the help section and I realized that it is used more than we think. Modulo is one way to calculate but here are other ways of course like manually calculating it like stated in previous figures. Here are some examples of using modulo in pawn practice:


Example 1)
You are in ajail because you broke the server rules and you want to know the time of still being in the ajail, so you contact the server scripter to script this. He would, in my honest opinion, write the code the best way by doing something like this:
pawn Code:
new minutes, seconds; //declare two integers (look E1)
new str[128]; //declare a string to hold everything

minutes = seconds / 60; //to get minutes you simply divide seconds / 60 as there are 60 seconds in one minute (easy math)
seconds = seconds % 60; //calculate modulo (look E2)

format(str, sizeof(str), "Time left: %i,%i", minutes, seconds); //using format to format everything into "str"

SendClientMessage(playerid, -1, str); //sending a message
E1: Delcare one integer holding minutes and one holding the seconds which should be the input from somewhere.
E2: Each time you have 60 seconds you want it to turn downwards into 0 right? Because 61 seconds doesn't exist in minutes (it does but you know...), so it will instead write 1 second instead of 61 seconds. So you take the float minutes and use modulo "%" with 60.

Discovery: Apparently by default if you do "minutes = seconds/60" minutes will always round downwards, so therefore no need to use "floatround".


Example 2)
You want to make so each time someone hits a 10-year anniversary you want to send message to congratulate them.
pawn Code:
new age, an; //declare a new float and an integer called "an"

an = age % 10; //calculate the age in 10-year anniversary terms (look E1)

if(an == 0) //asks if an is 0 (look E2)
{
    SendClientMessage(playerid, -1, "Congratulations on your anniversary!");
}
E1: Will "transform" so that whatever age is will be count into "10 terms" (mod 10). If age is 50 it will turn into 0. If age is 71 it will turn into 1.
E2: As we said, we wanted to make a congratulations each time someone turns a 10-years anniversary. We ask if an is equals to 0. If it is, it means the person is either 10, 20...etc. If not, it doesn't go inside the if-statement.



Additional notes:
Credits goes to e for writing the tutorial. All words are written by me. I really hope that this opens up a bit more knowledge to people reading this tutorial at least. I did not want to explain format or SendClientMessage more than I did because I didn't feel that it was important in this thread!

Credits for fixes:
pds2k12 - example code fix
Vince - English word fix
Reply
#2

First of all nice explanation, I read whole of the thread and I understood most of it, but you made some errors, you are using
Float tag but you are using %i/%d(Integer/Decimal) placeholder instead of %f (Float), you will also
get an error if you tried and compiled your code.

Error
Code:
error 004: function "operator%(Float:,_:)" is not implemented
Quote:
Originally Posted by Babul
View Post
the modulo operator returns the remainder of 2 integers. for floats, you simply need to reinvent the formula:
pawn Code:
new Float:a = 10.0;
new Float:b = 4.0;
new result=((a/b)-floatround((a/b),floatround_floor))*b;
Deeper Calculations
pawn Code:
3600.0 / 1500.0 = 2.4
floatround of 2.4 = 2.0
2.4 - 2.0 = 0.4
0.4 * 1500.0 = 600.0
Let me elaborate what Babul said, he said the modulo operator returns 2 (two) remainder of integer
you simply need to change the formala, as shown above.

Fixed Code
pawn Code:
new age, an; //declare a new float and an integer called "an"

an = age % 10; //calculate the age in 10-year anniversary terms (look E1)

if(an == 0) //asks if an is 0 (look E2)
{
    print("Congratulations on your anniversary!");
}
pawn Code:
new minutes, seconds; //declare a new float and an integer (look E1)

seconds = minutes % 60; //calculate modulo (look E2)
minutes = floatround(minutes, floatround_floor); //make the minutes become an integer (look E3)

printf("Time left: %i,%i", minutes, seconds);
- Correct me if I made something wrong.
Reply
#3

Haha sorry I'm so stupid. I messed up with example 1. I was for some reason thinking that you have the minutes already but in most times you get the input value of seconds or firstly in most cases milliseconds and then covert them into seconds. I fixed that anyways.

Also discovered that you don't need a float round at all as it is apparently by default rounding down when dividing (I did try to divide values that could have most likely been rounded upwards but instead was still rounded upwards. 50/60 was rounded down to 0. 110/60 was rounded down to 1 instead of up to 2.

This is basically what the modulo operator does:
Code:
new Float:a = 10.0;
new Float:b = 4.0;
new result=((a/b)-floatround((a/b),floatround_floor))*b;
I didn't understand it until now when I read it carefully:
(10/4 - quotaOf(10/4)) * 4 is what modulo does.

Thanks for reading and clarifying and pointing out fails!
Reply
#4

Thanks for tutorial , i have understand what i have searched for and didn't understand before. tnx again
Reply
#5

Quote:
Originally Posted by Hansrutger
View Post
Now you're asking what a rest is, look below:
Code:
Rest examples:
0.5 = Rest is 0.5
1.2 = Rest is 0.2 
5.852 = Rest is 0.852
1000000.52 = Rest is 0.52
Figure 3
It is everything after the comma sign. If you have larger numbers you will have to multiply the "rest" with the modulo number after removing anything to the left of the comma sign.
This is incorrect. What you're describing here is called the fractional part. The actual "rest" is the result of the modulo calculation.
Reply
#6

Quote:
Originally Posted by Vince
View Post
This is incorrect. What you're describing here is called the fractional part. The actual "rest" is the result of the modulo calculation.
Must have mistaken the words as I learned this in Sweden. We use "kvot" and "rest" for modulo. Don't know if that is the same as (****** translated) "quota" and "rest"? Anyways thank you I must have confused it, changed it!

@Sawalha - Thanks for reading!
Reply
#7

never know about modulo only knew modulus . i hope they are same. but ty for telling esp the the formula.
Reply
#8

Interesting tutorial, well explained.
Reply
#9

I'm really thankful to you, I have never known that this Modulo Operator did exist until you made this tutorial (apprearantly I did not study it yet) , this would certainly help me in my studies in the future, +rep
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)