Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Kyle Haddock
Courses Plus Student 169 PointsWhy is there an infinite loop here?? Don't see any possible reason.
I'm trying to write a program that calculates the greatest common factor of two numbers but it appears I'm getting an infinite loop. I really can't see any logical problems in my code. Can anyone else see a problem with it?
let bigNum;
let smallNum;
let num1;
let num2;
num1 = prompt('Enter an integer.');
while (isNaN(num1) ) {
if (num1 === null) {
break;
}
num1 = prompt('You need to enter a valid integer.');
}
num2 = prompt('Enter another integer.');
while (isNaN(num2) ) {
if (num2 === null) {
break;
}
num2 = prompt('You need to enter another valid integer.');
}
while (num1 === num2) {
num2 = prompt('You can\'t enter the same number twice! Enter a different integer.');
}
if (num1 === null || num2 === null) {
console.log('Refresh the page to run the program again.');
}
//checks to see which is the bigger of the two entered numbers
function numCheck(a, b) {
if (a > b) {
bigNum = a;
} else {
bigNum = b;
}
if (bigNum = a) {
smallNum = b;
} else {
smallNum = a;
}
}
numCheck(num1, num2);
//finds GCF using Euclid's algorithm
while (true) {
if (bigNum !== smallNum) {
bigNum -= smallNum;
} else {
break;
}
if (smallNum > bigNum) {
[bigNum, smallNum] = [smallNum, bigNum];
}
}
if (bigNum === smallNum) {
console.log('The GCF of ' + num1 + ' and ' + num2 + ' is ' + bigNum);
}
2 Answers
Steven Parker
243,656 PointsI believe I have found the original problem.
The reason that smallNum was able to become 0 had to do with the way the input was handled combined with the kind of test you did in the loop. Your "!==" is not simply an inequality test. It is a negated identity test, which means variables that represent the same value will still be considered not to match if they have different types.
And since prompt returns a string, the values stopped being the same type once one of them had been assigned the result of performing math on them, creating a number.
So to fix this, I made the prompt calls all arguments to parseInt, which converts the input to a number right away. Here's one example (you need to do the same with every prompt):
num1 = parseInt(prompt('Enter an integer.'));
Of course, a quicker fix would be to just replace the non-identity test (!==) with a simple inequality test (!=), but I did not like the idea of knowingly performing math on mixed types.
Also, I believe what you're computing here is called the GCD (not GCF).
Steven Parker
243,656 PointsAnytime smallNum becomes 0, the loop continues indefinitely.
When smallNum is 0, nothing changes in a pass through the loop. Does it need another test and break condition?
Also, around line 36 you have an assignment where you might have intended a comparison:
if (bigNum = a) {
But that whole function could be made more compact anyway:
function numCheck(a, b) {
[bigNum, smallNum] = (a > b) ? [a, b] : [b, a];
}
Kyle Haddock
Courses Plus Student 169 PointsBut smallNum should never become 0, since all numbers have a common factor of at least 1. Am I missing something here? And thanks, I didn't even notice that mistake on line 36.
Also, could you explain that function you wrote? I'm new to JS (and programming in general).
Steven Parker
243,656 PointsTry adding this to your loop as a "safety valve" to prevent infinite looping:
if (smallNum <= 0) { console.error(`smallNum is ${smallNum}!`); break; }
That should also convince you that it does happen. From there you can add some extra tests to determine why it happens.
I noticed you were already using destructuring assignment in your loop. Very sophisticated for a beginner! I just combined that with a ternary operation to reduce the numCheck function to a single line.
Kyle Haddock
Courses Plus Student 169 PointsI honestly have no idea what destructuring assignment is. I just saw someone suggest it on stackoverflow as a way to quickly swap the values of two variables.
Steven Parker
243,656 PointsThat's just a special case of assigning two values at once. Which is what I did for numCheck, using the ternary operation (?:) to pick one of the two possible orders to assign them from.
The ternary operation will be covered in one or more of the JavaScript courses here on Treehouse.
Kyle Haddock
Courses Plus Student 169 PointsKyle Haddock
Courses Plus Student 169 PointsThanks for your time, Steven. And thanks for making me aware of the ternary operator. That's going to be a huge time saver. I really can't believe I forgot to use parseInt! I feel like an idiot now lmao.
btw, GCF is just a synonym for GCD.