3

Below is a function that returns the prime factors of a given number in JavaScript. I did not write the function but have been studying it to extend my programming knowledge.

My questions are about the while loop that is inside the following if statement.

if(num % x){
    x = 3; 
    while((num % x) && ((x = x+2) < root));
}

Questions

  1. What is the purpose of a while loop if there is no code after it?
  2. What is happening when the while loop evaluates true?
  3. What is happening when the while loop evaluates false?

Here is the function in it's entirety.

function getPrimeFactors(num){
    num = Math.floor(num);
    var root = 0;
    var factors = [];
    var doLoop = 1 < num;
    var x = 0;

    while(doLoop){
        root = Math.sqrt(num);
        x = 2;

        if(num % x){
            x = 3;
            while((num % x) && ((x = x+2) < root));
        }

        if(x > root){
            x = num;
        }else{
            x = x;
        }

        factors.push(x);

        doLoop = (x != num);

        num = num/x;
    }

    return factors;
}

Thanks for the help!!!

kapa
  • 77,694
  • 21
  • 158
  • 175
JaredRogers
  • 33
  • 1
  • 1
  • 4
  • 2
    It changes the value of `x`. [While](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while) loop will continue looping untill its condition is evaluated to false. – Teemu Feb 11 '14 at 22:56

8 Answers8

3

It is really doing something like this:

if(num % x){

    x = 3;

    while(num % x){

        x = x + 2;

        if(x < root)
            continue;
        else
            break;
    }

}

Except, two is added to x right in the conditional, so there is no need for a body. The loop will execute until x < root or num % x fails to be true. The body just doesn't have any instructions in it.

Its very similar to what happens when you execute a for loop

for(int i=0; i < n; i++)
    ;

See there are no instructions in the for-loop body, but the loop will still add one to i until i >= n.

Joel
  • 4,732
  • 9
  • 39
  • 54
  • Well, actually not. `(num % x)` will use the current `x`, and `(x = x+2) < root)` will use the incremented `x`. – kapa Feb 11 '14 at 23:02
  • 1
    Still not entirely correct. The `x` variable in the original code is updated, even if `x + 2 < root` while this example does not change `x` in that case. – Robert Westerlund Feb 11 '14 at 23:05
  • My apologies for not spending tons of time guaranteeing the correct output, I was more concerned with explaining the concept to the OP. – Joel Feb 11 '14 at 23:09
  • That is a good approach. We only want to help make your explanation more accurate. – Robert Westerlund Feb 11 '14 at 23:13
  • The purposed solution does not work with all numbers. Specifically when you input 144. Your example outputs [2, 2, 2, 2, 9] and it should output [2, 2, 2, 2, 3, 3]. – JaredRogers Feb 12 '14 at 01:12
  • @JaredRogers quite honestly, I am fine with that. There is no need to rewrite the code if it is functional. I was just trying to help you understand what is happening. Notice I prefaced the code with _something like this_. – Joel Feb 12 '14 at 03:40
  • @JaredRogers My latest edit should reflect an accurate expansion of the code. – Joel Feb 12 '14 at 03:47
  • @Joel Thanks for updating your response to accurately represent the same functionality. I get what you were saying about getting the gist of it but I think the details are important. If an example doesn't accurately represent something it can cause more misunderstanding. Again thank you for your time and the explanation. – JaredRogers Feb 12 '14 at 06:16
2

Note the x = x+2 in the while statement. It adds 2 to the value of x repeatedly until the while clause evaluates true.

So a while loop without a body blocks execution until it's clause becomes true. This is only a good idea if you you are mutating a variable in the clause as part of the condition. Otherwise you may end up in an infinite loop.

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
2

This code says, in effect, that if x is not evenly divisible by 3, then add 2 to x and continue if the resulting value is less than root. The loop terminates as soon as one of these conditions is no longer true, but, meanwhile, x has been updated along the way.

Note that x = x + 2 evaluates to the assignment's left operand.

Wayne
  • 59,728
  • 15
  • 131
  • 126
1

There is actually one thing happening in the loop:

                       V
while((num % x) && ((x = x+2) < root));

x = x + 2 is an assignment, you can see it is not a == or === operator but a =.

(x = x + 2) < root means increment x by 2, and then compare it to root.

Using an assignment in the condition part of a while or if statement is generally not recommended, because it makes the code less readable.

kapa
  • 77,694
  • 21
  • 158
  • 175
1

The while statement there does change the value of the x variable. It could be rewritten as something like the following:

if (num % x) {
    x = 3;
    if (num % x){
        do {
            x = x + 2;
        } while (num % x && x < root);
    }
}
Robert Westerlund
  • 4,750
  • 1
  • 20
  • 32
  • I totally missed the = (assignment) vs == (comparison). I was thrown because I have never seen a loop without a body. Thank you this solution works properly and is easier to visualize. – JaredRogers Feb 12 '14 at 01:34
0

The value of x is incremented (by 2) until it is equal to or greater than the value of root

Jason
  • 2,503
  • 3
  • 38
  • 46
0

There's an assignment in the while condition/loop. It's evaluated while the loop is running so the value of "x" gets updated every cycle until no longer < root ( besides/and: && num % x < root).

Very clever but I hope this is not an introduction text/book/post to programming.

Allende
  • 1,480
  • 2
  • 22
  • 39
  • 2
    No, it wasn't a beginners book. I have been doing Project Euler problems and when I get stuck I search for pieces of functionality that I wasn't able to do on my own. Then I tear them apart and evaluate them to expand my knowledge on the subject. – JaredRogers Feb 12 '14 at 00:25
0

It seems like your hang-up you're having is with the fact that there's no body in the while statement. Understand that a loop body is optional and that it it behaves in the same way as a loop that does have a body.

Basically the while loop will repeatedly check the condition over and over. Yes, this can result in an infinite loop if coded incorrectly. In this case, 'x' will be incremented by 2 until it reaches or exceeds the value of 'root'.

credit to @Teemu for "reaches or"

user2910265
  • 844
  • 1
  • 9
  • 15