Legacy GM Modulo is unproperly calculated ?

R

Rackover

Guest


-1%5 is supposed to give 4, not -1
Why does Game Maker say otherwise ?
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
There is no "standard" or specification on what the output of modulo on negative numbers should be, so you may find different implementations to approach this differently (wiki)
 

Surgeon_

Symbian Curator
Modulo X % Y is basically:
- While X >= Y, subtract Y from X
- While X < 0, add Y to X
So in this case 4 looks fine to me.
 
H

Homunculus

Guest
Noticed that too, I'm not really sure if that's intended or not (maybe both solutions are correct, in some sense). In other languages like ruby you actually get 4.
 

Surgeon_

Symbian Curator
After some googling I realized that I (and probably some of you) were thinking about congruence relation in mathematics, and computer implementations of mod don't always follow that for the mod operator, as we can see here.
 

zbox

Member
GMC Elder
The opposite way to the method Gamemaker implements modulo has always been more useful to me unfortunately
 

GMWolf

aka fel666
mod and % is not the modulo operator.
Its the remainder operator.

Its really annoying, especially when doing cryptography.
 
W

Wraithious

Guest
If you want to feed mod a negative number (like -1 and have it to return 4) just make a small script like:
Code:
//customMod(inNum, modNum)
{
var inNum = argument0;
var modNum = argument1;

if inNum >= 0
return inNum mod modNum;

if inNum < 0
return (inNum * -1) mod modNum;
}
 
H

Homunculus

Guest
If you want to feed mod a negative number (like -1 and have it to return 4) just make a small script like:
This doesn't look correct to me. The sample case with -1 mod 5 with your script will return 1 instead of 4.
 

Miradur

Member
Maybe so, but what´s the point?

Code:
//customMod(inNum, modNum)
{
var inNum = argument0;
var modNum = argument1;

if inNum >= 0
return inNum mod modNum;

if (inNum < 0) && (inNum * -1 < modNum) {
     return modNum - ((inNum * -1) mod modNum )
} else {
     return (inNum * -1) mod modNum;
}
Miradur
 
H

Homunculus

Guest
Assuming mod is consistent in this behavior among all export modules, you can simplify the script to this:

Code:
/// @desc mod2(a,b)
/// @arg a
/// @arg b

var a = argument0;
var b = argument1;

return (b + (a mod b)) mod b;
Don't know if it's more or less efficient than checking the values with an if, but hey, it's essentially a one liner :)
 
Last edited by a moderator:
W

Wraithious

Guest
You guys are right, sorry i didnt test my script.
It's debatable on what the correct output of -1 mod 5 would actually be, I would think it could possibly be 6. Let me explain, say you stock 5 items. Someone orders 6. You send him 5 and owe him 1. But interestingly the remainder that you now have to make or aquire is 6 to restock to inventory of 5.
But on the other hand the remainder is actually -1 because you promised 6 and had 5.
And on the 3rd hand (for those that have 3 hands lol) the remainder would be 1 because that's the remainder you need to complete your order.
This topic is frustrating haha
 

GMWolf

aka fel666
You guys are right, sorry i didnt test my script.
It's debatable on what the correct output of -1 mod 5 would actually be, I would think it could possibly be 6. Let me explain, say you stock 5 items. Someone orders 6. You send him 5 and owe him 1. But interestingly the remainder that you now have to make or aquire is 6 to restock to inventory of 5.
But on the other hand the remainder is actually -1 because you promised 6 and had 5.
And on the 3rd hand (for those that have 3 hands lol) the remainder would be 1 because that's the remainder you need to complete your order.
This topic is frustrating haha
-1 mod 5 is 4.
It cannot be 6, x mod N will always be less than N.

Modular arithmetic is a properly defined thing.
It was properly defined by gauss in the 1800s.
You can't really debate it.
It has proper theorems built around it.
It's the base of most of modern cryptography (RSA, diffie helman, elliptic curves, etc).
You can't just debate the rules.
 

CloseRange

Member
Game maker handles mod by first setting n to positive, taking the mod, then setting it back to negative later.
1 mod 5 is 1 so to them -1 mod 5 is just -1.
Game Maker thinks you mean this:
Code:
-(1 % 5)
This has the advantage that it's easy to identify weather or not n is negative just by the result (Not much of an advantage)
What you want is remainder(-1 / 5) but this gives -remainder(1 / 5).
The easy to get what you want is to do as @flyingsaucerinvasion said and just divide n with a and get the remainder by hand.
Code:
/// Nmod(n, a);
var n = argument[0];
var a = argument[1];
return n - floor(n / a) * a;
 
Top