0

I wrote a function to calculate the modulus of a function but when I run it in the console it always returns undefined. If I use the console.log I can see that it is calculating the correct value.

function modulo(sum, divider){ 
  function loop(difference){ 
    if(difference < divider){ 
     console.log(difference)
     return difference
    } else { 
       setTimeout(loop(difference - divider), 0)
    } 
  } 
  
  return loop(sum - divider) 
}

modulo(8, 5) // 3

what I want is this to return the answer e.g.

var result = modulo(8, 5) // 3

Update:

A better solution to this problem would be

modulo = function (x,y){ return x - y * Math.floor(x/y) }

Peter
  • 4,493
  • 6
  • 41
  • 64
  • 2
    Note: `setTimeout()`, if used correctly, would make the `function` asynchronous / event-driven and unable to `return` under current standards. See "[Why is my variable unaltered after I modify it inside of a function?](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron)" And, for why I say "*if used correctly*," see "[Why is the method executed immediately when I use setTimeout?](http://stackoverflow.com/questions/7137401/why-is-the-method-executed-immediately-when-i-use-settimeout)" – Jonathan Lonowski Oct 16 '14 at 15:19
  • Thanks for the comments Jonathan :-) – Peter Oct 17 '14 at 08:23

3 Answers3

3

You don't need to create a new function for this, JavaScript already has it's own modulus operator: %.

8 % 5
-> 3

If you really want to turn this into a function, you can simply:

function modulo(sum, divider) {
    return sum % divider;
}
modulo(8, 5);
-> 3
James Donnelly
  • 126,410
  • 34
  • 208
  • 218
2

To answer your original question, setTimeout is asynchronous, and your loop function returns undefined, hence you get undefined. To make it do what you want, call loop directly, or use promises.

But on the other hand, even if you were to implement modulus, this is a poor approach. Use some better division algorithms instead.

simonzack
  • 19,729
  • 13
  • 73
  • 118
  • Do you mean this gcd formula? `function gcd(a, b) if b = 0 return a else return gcd(b, a mod b)` Could you please explain further? – Peter Oct 16 '14 at 16:09
  • Ah! Got it -`mod = function (x,y){ return x - y * Math.floor(x/y) }` – Peter Oct 17 '14 at 09:33
0

Because your code does not return value from the loop.

Try this:

function modulo(sum, divider) {
  function loop(difference) {
    if (difference < divider) {
      return difference;
    } else {
      return loop(difference - divider);
    }
  }

  return loop(sum - divider);
}

alert(modulo(8, 5));
cychoi
  • 2,890
  • 3
  • 22
  • 31