0

I was doing a kata on code wars and discovered that

    function findNextSquare(sq) {
     var rt = Math.sqrt(sq);
     console.log((rt++)**2)
     return rt%1 !== 0 ? -1 : ((rt++)**2); 
    } //>> 144

whereas

    function findNextSquare(sq) {
     var rt = Math.sqrt(sq);
     //console.log((rt++)**2)
     return rt%1 !== 0 ? -1 : ((rt++)**2); 
    } //>> 121

Which is to say that, simply commenting out the console.log causes a different return value...

Also, worth note: the first console logs 121, rather than 144.

Here it is on repl.it: https://repl.it/languages/javascript

I wonder if this has to do with asynchronicity. Can someone explain why removing the console.log changes the return?

1
  • 4
    because you are increasing rt value in console log by doing rt++ Commented Jul 10, 2017 at 9:07

4 Answers 4

7

Quick solution:

function findNextSquare(sq) {
  var rt = Math.sqrt(sq);
  return rt % 1 !== 0 ? -1 : (rt + 1)**2; 
}

Explanation:

This has nothing to do with asynchronicity.

rt++ in console.log((rt++)**2) causes the rt variable to be incremented. Therefore, rt will be different (one more than it should be) when it gets to the return line.

Note the difference:

  • rt + 1 is an expression that adds 1 to rt and returns the result — rt stays unchanged
  • rt++ adds 1 to rt, saves the result back to rt, and returns the old rt
  • ++rt adds 1 to rt, saves the result back to rt, and returns the new rt

Let's see what your original code did with sq = 16, with the console.log not commented out:

function findNextSquare(sq) {            // sq = 16
  var rt = Math.sqrt(sq);                // rt = 4
  console.log((rt++) ** 2);              // logs 4^2 = 16, rt incremented to 5
  return rt % 1 !== 0 ? -1 : (rt++)**2;  // returns 5^2 = 25, rt incremented to 6 (unneeded)
}

When you remove console.log, this is the result:

function findNextSquare(sq) {            // sq = 16
  var rt = Math.sqrt(sq);                // rt = 4
  return rt % 1 !== 0 ? -1 : (rt++)**2;  // returns 4^2 = 16, THEN rt is incremented to 5
}

The solution is to add 1 to rt and then square the new value. We don't actually need to save the new value back to rt:

function findNextSquare(sq) {              // sq = 16
  var rt = Math.sqrt(sq);                  // rt = 4
  return rt % 1 !== 0 ? -1 : (rt + 1)**2;  // returns (4 + 1)^2 = 25
}

If you want a console.log in there, you can have it, just make sure it does not change rt:

function findNextSquare(sq) {
  var rt = Math.sqrt(sq);
  console.log((rt + 1) ** 2);
  return rt % 1 !== 0 ? -1 : (rt + 1) ** 2; 
}
Sign up to request clarification or add additional context in comments.

Comments

4

The statement console.log((rt++)**2) has the side effect of increasing rt by 1.

Commenting it out obviously has the effect of rt being one less, which accounts for the difference between 121 (11 * 11) and 144 (12 * 12).

Comments

2

The ++ operator automatically increments the given variable. And its not just for the console.log().

What happens when you do variableName++; is equal to writing

variableName = variableName + 1;

so whether you have used the ++ operator inside a console.log() or somewhere else, the variable gets incremented for good.

Be careful how you use it. If you want to still use the console log with incremented variable, I would suggest using console.log(variableName + 1);

Hope this helps!

Comments

2

Expression used in console.log increments rt value.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.