6
votes

For a homework assignment, I need to return the remainder after dividing num1 by num2 WITHOUT using the built-in modulo (%) operator. I'm able to get most tests to pass with the following code, but I'm stuck on how to account for -/+ signs of the given numbers. I need to carry over whichever sign is on num1, and also return a positive number if the num2 is negative - it's blowing my mind how to do this... :) Any clarity would be greatly appreciated! I'm not exactly looking for the straight up answer here, more that I seem to be missing something obvious... Maybe I need a new approach?

    function modulo(num1, num2) {
      if (num1 === 0) {
        return 0;
      }
      if (num2 === 0 || isNaN(num1) || isNaN(num2)) {
        return NaN;
      }
      if (num1 < num2) {
        return num1;
      }
      if (num1 > 0 && num2 > 0) {
        var counter = num1;
      while (counter >= Math.abs(num2)) {
        counter = counter - num2;
      }
      return counter;
      }
    }
    var output = modulo(25, 4);
    console.log(output); // 1
2
What is the expected output for e.g. modulo(-25, 4) and modulo(25, -4)?Jordan Running
Btw, % is the remainder operator in JavaScriptBergi

2 Answers

7
votes

If you think about the mathematical process to calculate modulus you might be able see how you can do this without having to resort to a bunch of case statements. Instead think of it this way, you're just calculating a remainder:

Given 2 numbers a and b, you can compute mod(a,b) by doing the following:

q = a / b;  //finding quotient (integer part only)
p = q * b;  //finding product
remainder = a - p;  //finding modulus

Using this idea, you should be able to transfer it to JS. You said you're not looking for the straight up answer so that's all I'll say!

Edit: here is the code, like I said in the comments it's exactly the pseudocode I posted above:

function modulo(a,b){
  q = parseInt(a / b);  //finding quotient (integer part only)
  p = q * b;  //finding product
  return a - p;  //finding modulus
}

This will return the exact same values as using %

0
votes

You might be overthinking this. You basically stated the solution in your question:

I need to carry over whichever sign is on num1, and also return a positive number if the num2 is negative

The second part isn't accurate, but I suspect you just misspoke. A positive number should be returned when num2 is negative unless num1 is negative.

At any rate, the important takeaway is that if num1 is negative the result will be negative, and otherwise the result will be positive. The sign of num2 is discarded.

Starting the code you've written (which others will be quick to point out isn't the simplest solution), the fix is to compute the remainder using both numbers' absolute values, and then apply num1's original sign to the result.

function modulo(num1, num2) {
  var sign = num1 < 0 ? -1 : 1;
  var dividend = Math.abs(num1);
  var divisor = Math.abs(num2);

  if (dividend === 0) {
    return 0;
  }
  if (dividend === 0 || isNaN(dividend) || isNaN(divisor)) {
    return NaN;
  }
  if (dividend < divisor) {
    return sign * dividend;
  }
  
  var counter = dividend;
  while (counter >= divisor) {
    counter = counter - divisor;
  }
  return sign * counter;
}

console.log( 25 %  4, modulo( 25,  4));
console.log(-25 %  4, modulo(-25,  4));
console.log( 25 % -4, modulo( 25, -4));
console.log(-25 % -4, modulo(-25, -4));
.as-console-wrapper{min-height:100%;}