Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Math.Mod ????

Discussion in 'Scripting' started by crazyosachou, Oct 6, 2010.

Thread Status:
Not open for further replies.
  1. crazyosachou

    crazyosachou

    Joined:
    Sep 27, 2010
    Posts:
    176
    hi,

    in Maxscript and more other languages, i used to use Math.Mod (gives the rest of the exacte division of A on B)

    i didn't found it in UNITY :s :s
     
  2. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    That's because the modulo operator is part of the language:
    Code (csharp):
    1. remainder = number % divider;
     
  3. crazyosachou

    crazyosachou

    Joined:
    Sep 27, 2010
    Posts:
    176
    thanks dude ;)
     
  4. reddtoric

    reddtoric

    Joined:
    Mar 7, 2017
    Posts:
    7
    Tymianek, tjumma and abermann_O like this.
  5. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,367
    That went nine years without saying.
     
    dchacke, Predulus, Tymianek and 3 others like this.
  6. Tymianek

    Tymianek

    Joined:
    May 16, 2015
    Posts:
    97
    Here is an example of a(mod n) imlemented using the remainder operator:
    Code (CSharp):
    1. int Mod(int a, int n) => (a % n + n) % n;
    Note that

    Code (CSharp):
    1. -1 % 100 == -1
    2. Mod(-1, 100) == 99
     
    Last edited: Mar 5, 2021
  7. Tymianek

    Tymianek

    Joined:
    May 16, 2015
    Posts:
    97
  8. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,514
    So y'all necroing a post to basically repeat statements already stated:

    ...

    Also... the hilarious part is.

    OK, so % is not a modulo, it's the remainder operator.

    What is modulo though?
    https://en.wikipedia.org/wiki/Modulo_operation

    OH... modulo returns the remainder.

    Read through the entire article... there technically is different ways to algorithmically calculate your modulo. But they're all referred to as modulo. The terms are interchangeable in a programming sense. Note the list of mod and which way it works. Which yes some people will refer to as remainder vs modulo. But at the end of the day... we call it mod. And necroing an ancient post to correct something so pedantic as under what context one should use this word or that word (with out actually explaining why either)... is dumb.

    So... to anyone reading this thread (since it appears to be so popular) and wondering why the heck so many people felt it necessary to say % in C# isn't mod. Well... see the wikipedia article for why it's perfectly fine to call it mod, but to understand that there are 2 ways the operation may be implemented depending on the language you use. Because at the end of the day... if you're looking to use mod, you're probably looking for the remainder, which means... %, the modulo/remainder operator, is going to do what you expect. If you're looking to do anything more complicated than that, then you're probably a math guy and are well versed in the nuances.
     
    Last edited: Mar 6, 2021
    ZO5KmUG6R likes this.
  9. Tymianek

    Tymianek

    Joined:
    May 16, 2015
    Posts:
    97
    I found this post when googling mod in c# unity, expecting to find Mathf.Mod method. So I posted a solution to the problem and also referenced the official docs, so people don't have to go through stack overflow responses.
     
  10. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,992
    The explanation I heard way, way back was that %, called modulo, works just fine for non-negative numbers. It works "wrong" on negatives, for technical reasons, but that's fine since you never need it for them and also since not many people know it's wrong -- that a proper modulo is from 0 to n-1.

    And in practice it works out. For example n=(n-1)%length should subtract 1, wrapping 0 over to length-1, but doesn't. Which is fine since adding length-1 also works, and is all positives, and reads well once you get used to it (and have taken that 1 required math course on fields): n=(n+(length-1))%length. Also, you rarely subtract 1 anyway, mostly add.
     
  11. vycanis1801

    vycanis1801

    Joined:
    Feb 11, 2020
    Posts:
    12
    renecroing this thread to add that yes for some applications the "wrong" modulo is wrong. If you're using a ring buffer for example in a fighting game to see if there are inputs available to execute a certain action. One way to insert into the input buffer would be:

    Code (CSharp):
    1. private static readonly BUFFER_SIZE = 60;
    2. private int _counter = 0;
    3. private int _attackValue = 0; // set where ever you handle input events
    4. private int[] _inputBuffer = new int[BUFFER_SIZE];
    5.  
    6. private void FixedUpdate() {
    7.     _counter++;
    8.     _inputBuffer[count % BUFFER_SIZE] = _attackValue;
    9. // ... continued bellow
    10. }
    11.    
    Before you're game executes an action you need to look back through old inputs which can be done like this (based an answer from SO. I'd give proper credit but I can't remember the thread or author.)

    Code (CSharp):
    1. // If you are unfamiliar with fighting game terminology google "fighting game num pad notation"
    2. private int[] quarterCircleForward = { 2, 3, 6 };
    3. private bool CheckSequence(int[] sequence, int distanceInPast) {
    4.     for(int i = 0; i < distanceInPast; i++) {
    5.          int index = (counter % BUFFER_SIZE) - i;
    6.          // ... the rest of comparing what's in the buffer vs some sequence
    7.     return false; // return true if the sequence was found in the buffer
    8. }
    9.  
    10. private void FixedUpdate() {
    11.     //...continued from above
    12.    CheckSequence(quarterCircleForward, 3);
    13. }
    14.  
    The problem with
    Code (CSharp):
    1. (counter % BUFFER_SIZE) - i
    is that if your counter variable is on frame zero, when you get to i = 1, c# calculates 0 - 1 = -1 % 60 = -1. Which will make your input buffer crash because _inputBuffer[-1] is invalid.

    So yeah sometimes it is important, and maybe language developers should make these kind of distinctions.
     
  12. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,919
    But it's still not "wrong", it may simply not be what you expect, but that's an issue on your side ^^. The modulo / remainder operator fulfills this property:

    Code (CSharp):
    1. int a = -5;
    2. int b = 4;
    3.  
    4. int q = a / b;  // -1
    5. int r = a % b; // -1
    6.  
    7. int c = q * b + r; // -1 * 4 - 1 == -5
    8.  
    9. if (c == a) // true
    10.  
    That's the general idea behind the remainder. It's the rest of the number that could not be divided. So doing an integer division gives you what you usually would expect. If you define the integer division mathematically correct where the remainder is always positive, that would mean dividing
    -1
    by
    5
    would give you
    -1
    and a remainder of
    4
    . So
    -1 * 5 + 4
    brings us also back to the original
    -1
    . However this is almost never useful in programming. Some programming languages do this, but most don't. The issue is that integer division is not uniquely defined.
     
    nijnstein likes this.
Thread Status:
Not open for further replies.