GML What is "%" used for in GML? Something related to "mod"...?

FoxyOfJungle

Kazan Games
Hi! I looked in several places, even in the manual:



And it was never clear what the purpose of using % in GML was, I also never saw anyone using it in other languages until now (they may be using it, but I didn't).
However I have seen GM users using it and I am curious to know how it works.


Extra:
How are these unary operators used? What occasions could I use? (Not counting the "!", I already know that one).
  • -
  • ~

I will be grateful for the help! :)
 

drandula

Member
% is short for mod operator.
Unary "-" is just negating the value.
"~" i remember being "bit not", so it flips 0 to 1 and 1 to 0 in bit number.

Edit. Sorry about short answer, on mobile
Edit2. Unary operator means operator which takes only one "operand", in this case number. So in "-1" the"-" is unary operator negating the "1". But in "2-1" the "-" is binary operator subtract, taking two operands.
And just to mention the "?" (For example "(true) ? 0 : 1") is ternary operator as it takes three operands.
 
Last edited:

Alice

Darts addict
Forum Staff
Moderator
It's fairly common (if maybe not used much) in other languages, e.g. here's an excerpt from C# docs.

As for using it in games: I've found it pretty common when e.g. using a grid and converting between the index-of-cell value and column-row values. For example:
- we have a 10x10 grid
- the 0th row has 0th-9th cells, the 1st row has 10th-19th cells etc. until the last row with 90th-99th cell
- to get the index from column/row values, we do var cell_index = grid_width * cell_row + cell_column;
- to get the column/row values back from the cell index we do var cell_row = cell_index div grid_width; var cell_column = cell_index mod grid_height; (or you can replace mod with %)

Hope this gives you an idea of at least one case where the remainder operator is useful. Other use-cases could include e.g. looping back to 0 degrees after doing a full 360 turn:
angle += 1; angle = angle % 360;

As for -/~ unary operators:
"-" operator is just for negative numbers. For example, if you do var value = -42;, then the "-" is the unary operator here; without it, the value would be plus 42 rather than minus 42.
"~" operator is for bitwise negation, which flips 0s and 1s in a binary representation of a given value. So if you have value variable ending with 00111010, then ~value will end with 11000101 instead. Bitwise operations in general are fairly rare, but in certain cases can be useful (especially if you want to tuck many 0/1 flags in a single value).
 

NightFrost

Member
Since using mod with angles came up, note that in GML the operation does not run as it might in some other languages. Namely, it will not wrap around negative numbers. For example if the value of angle were 10 and you wrote (angle - 20) mod 360 you may be expecting to get 350 which would be the correct "wraparound" result, but GML returns -10 instead. If you want to implement a freely rotating angle value you must check for the threshold values manually instead of relying on mod.
 

Mr Magnus

Viking King
The modulo operator has two major uses:

* See if a given number is divisible by some other number
* Keep a certain positive value within some range


The general idea of (a mod b) is that it's the reminder you get when dividing a by b. It's hugely important and shows up all the time in computer science. Cryptography is littered with the thing and would be impossible without it. This is also commonly referred to as "clock arithmetic" when teaching it to children. It's essentially "math on a clock". When you get to 11 you don't go to twelve, you go to zero and start again.

So, as an example let's do a few examples:
  • 4 mod 2 = 0 (4 divides perfectly in to 2 with no remainder)
  • 6 mod 4 = 2 (6/4 = 1, with two remaining)
  • 29 mod 11 = 7 (29/11 = 2, with seven remaining)
  • 100 mod 10 = 0 (100/10 = 10, 0 remaining)


In gamemaker mod can be used for:

  • checking if a number is even ( n % 2 = 0 for even values of n, 1 for odd values)
  • Making something happen ever n steps in a loop ( if( i % 10 == 0) will trigger for every ten increments of i, at i=0,10,20,30,40)
  • Making sure angles stay between 0 and 360 (Albeit as pointed out negative numbers can cause the range to be -360 to 360. While gml angle functions won't care your functions need to account for it)
  • if you're counting seconds in a single value you can split them in to minutes and hours with mod and div [ h = seconds div (60*60), m = seconds div 60 % 60, s = seconds%60)
  • Round a number down to the nearest multiple of some other number ( n - (n%10) will round n down to the nearest multiple of 10 )
  • Wrapping around array indices to make sure you'll keep within an array boundary even if you know it will shoot out of bounds as part of the loop.
  • As part of the caluclation of hash values for a hash table. For instance a chess AI may store states it has encountered in a hash table and needs thus the ability to hash the state of the game quickly
 
Since using mod with angles came up, note that in GML the operation does not run as it might in some other languages. Namely, it will not wrap around negative numbers. For example if the value of angle were 10 and you wrote (angle - 20) mod 360 you may be expecting to get 350 which would be the correct "wraparound" result, but GML returns -10 instead. If you want to implement a freely rotating angle value you must check for the threshold values manually instead of relying on mod.
This has nothing to do with the modulo at all, mate. Modulo is the remainder of a division, and you're talking about angles?!?
Oh, and you have degtorad and radtodeg functions, exactly to deal with what you describe! ;)
 

drandula

Member
This has nothing to do with the modulo at all, mate. Modulo is the remainder of a division, and you're talking about angles?!?
Oh, and you have degtorad and radtodeg functions, exactly to deal with what you describe! ;)
GML mod behaves funny with negative numbers, which Nightftost was talking about.
And you can use mod to keep angle between 0 and 360, using "angle mod 360". But this only works for positive numbers in GML.

Edit. And with "angle div 360" you can get your many full rounds you get.
 
GML mod behaves funny with negative numbers, which Nightftost was talking about.
Mod with negative numbers are unintuitive. The modulo result always has the same sign as the value you feed it.
This behavior is sometimes shady for a lot of people as it's not what we were taught in elementary school, but this is perfectly normal.
Eg:
GML:
var n = -4 % 3;    //Outputs -1
Unless there's a specific case you are thinking of that I'm not aware of! Feel free to share, cuz I use % all the time, I'd hate to work on bugs and stuff without knowing it!!
 

FoxyOfJungle

Kazan Games
% is short for mod operator.
Unary "-" is just negating the value.
"~" i remember being "bit not", so it flips 0 to 1 and 1 to 0 in bit number.

Edit. Sorry about short answer, on mobile
Edit2. Unary operator means operator which takes only one "operand", in this case number. So in "-1" the"-" is unary operator negating the "1". But in "2-1" the "-" is binary operator subtract, taking two operands.
And just to mention the "?" (For example "(true) ? 0 : 1") is ternary operator as it takes three operands.
It's fairly common (if maybe not used much) in other languages, e.g. here's an excerpt from C# docs.

As for using it in games: I've found it pretty common when e.g. using a grid and converting between the index-of-cell value and column-row values. For example:
- we have a 10x10 grid
- the 0th row has 0th-9th cells, the 1st row has 10th-19th cells etc. until the last row with 90th-99th cell
- to get the index from column/row values, we do var cell_index = grid_width * cell_row + cell_column;
- to get the column/row values back from the cell index we do var cell_row = cell_index div grid_width; var cell_column = cell_index mod grid_height; (or you can replace mod with %)

Hope this gives you an idea of at least one case where the remainder operator is useful. Other use-cases could include e.g. looping back to 0 degrees after doing a full 360 turn:
angle += 1; angle = angle % 360;

As for -/~ unary operators:
"-" operator is just for negative numbers. For example, if you do var value = -42;, then the "-" is the unary operator here; without it, the value would be plus 42 rather than minus 42.
"~" operator is for bitwise negation, which flips 0s and 1s in a binary representation of a given value. So if you have value variable ending with 00111010, then ~value will end with 11000101 instead. Bitwise operations in general are fairly rare, but in certain cases can be useful (especially if you want to tuck many 0/1 flags in a single value).
The modulo operator has two major uses:

* See if a given number is divisible by some other number
* Keep a certain positive value within some range


The general idea of (a mod b) is that it's the reminder you get when dividing a by b. It's hugely important and shows up all the time in computer science. Cryptography is littered with the thing and would be impossible without it. This is also commonly referred to as "clock arithmetic" when teaching it to children. It's essentially "math on a clock". When you get to 11 you don't go to twelve, you go to zero and start again.

So, as an example let's do a few examples:
  • 4 mod 2 = 0 (4 divides perfectly in to 2 with no remainder)
  • 6 mod 4 = 2 (6/4 = 1, with two remaining)
  • 29 mod 11 = 7 (29/11 = 2, with seven remaining)
  • 100 mod 10 = 0 (100/10 = 10, 0 remaining)


In gamemaker mod can be used for:

  • checking if a number is even ( n % 2 = 0 for even values of n, 1 for odd values)
  • Making something happen ever n steps in a loop ( if( i % 10 == 0) will trigger for every ten increments of i, at i=0,10,20,30,40)
  • Making sure angles stay between 0 and 360 (Albeit as pointed out negative numbers can cause the range to be -360 to 360. While gml angle functions won't care your functions need to account for it)
  • if you're counting seconds in a single value you can split them in to minutes and hours with mod and div [ h = seconds div (60*60), m = seconds div 60 % 60, s = seconds%60)
  • Round a number down to the nearest multiple of some other number ( n - (n%10) will round n down to the nearest multiple of 10 )
  • Wrapping around array indices to make sure you'll keep within an array boundary even if you know it will shoot out of bounds as part of the loop.
  • As part of the caluclation of hash values for a hash table. For instance a chess AI may store states it has encountered in a hash table and needs thus the ability to hash the state of the game quickly
Mod with negative numbers are unintuitive. The modulo result always has the same sign as the value you feed it.
This behavior is sometimes shady for a lot of people as it's not what we were taught in elementary school, but this is perfectly normal.
Eg:
GML:
var n = -4 % 3;    //Outputs -1
Unless there's a specific case you are thinking of that I'm not aware of! Feel free to share, cuz I use % all the time, I'd hate to work on bugs and stuff without knowing it!!

Ohh !!
So it means that I can use % instead of mod, this is really cool. I will always use now lol (How did not I think of this before? Supposedly it was in the manual in parentheses XD)
mod is very good to do several things, like watches, a revolving safe system, something with angles as mentioned above...

Thank you very much for your help and examples, it was super clear, they were very useful! ❤
 

GMWolf

aka fel666
In GM mod and % return the remainder. Not the modulo.
-4 modulo 3 is (congruent) 2. Not -1.

It's a misnomer, but matches what other languages do too.
 

FoxyOfJungle

Kazan Games
In GM mod and % return the remainder. Not the modulo.
-4 modulo 3 is (congruent) 2. Not -1.

It's a misnomer, but matches what other languages do too.
If that's what I'm thinking, for module in math, we have abs() in GML, which converts the negative signs into positive ones. Like: | -123 | = 123.
 

GMWolf

aka fel666
If that's what I'm thinking, for module in math, we have abs() in GML, which converts the negative signs into positive ones. Like: | -123 | = 123.
That doesn't work. It's a bit more complicated.

-4 is congruent 2 modulo 3
(-4 modulo 3 = 2)

But in GM abs(-4 mod 3) = -1.

A correct formula for modulo arithmetics would be
(((a % b) + b) % b)

However modulo is painfully slow.
So this could be better:
var c = a % b;
return (c < 0) ? c + b : c


(I used % and mod interchangibly here. That's because they are. they do the same thing)
 

FoxyOfJungle

Kazan Games
That doesn't work. It's a bit more complicated.

-4 is congruent 2 modulo 3
(-4 modulo 3 = 2)

But in GM abs(-4 mod 3) = -1.

A correct formula for modulo arithmetics would be
(((a % b) + b) % b)

However modulo is painfully slow.
So this could be better:
var c = a % b;
return (c < 0) ? c + b : c


(I used % and mod interchangibly here. That's because they are. they do the same thing)
Wow, cool! I didn't know that, interesting... 🤔 Thank you!
 
In GM mod and % return the remainder. Not the modulo.
-4 modulo 3 is (congruent) 2. Not -1.

It's a misnomer, but matches what other languages do too.
But to be fair, aside from Fortran (that I know of, which has both mod() and rem()), all programming languages behave like GM does, carrying the sign over to the remainder.
It's rarely ever going to come back and bite you if you just see it as an integer division (if ever, in GML), but you're totally right, there's a subtlety here.
 

GMWolf

aka fel666
But to be fair, aside from Fortran (that I know of, which has both mod() and rem()), all programming languages behave like GM does, carrying the sign over to the remainder.
It's rarely ever going to come back and bite you if you just see it as an integer division (if ever, in GML), but you're totally right, there's a subtlety here.
Given how GM users like to code all sorts.of crazy things that should never be written in GM I'm sure someone out there ran into it when writing cryptographic primitives from scratch in GML.
 
Top