Pete
Pete

Reputation: 117

Javascript: confusion on using Logical NOT ! Operator

I am slightly confused on the logical NOT operator in Javascript (!). From my understanding, this is mainly used to "inverse" a boolean value. For example, if an expected output of a boolean is true, putting this in front would turn it to false, and vice versa.

In my below code, I created a function allowing user to input a lower and upper integer, and the function would generate a random number between this range. If, however, the user inputs a string instead of an integer, it will prompt the user to enter an integer instead.

I am using isNaN to check if user's input is an integer, and using logical NOT operator in front of it to inverse the result.

In my if condition, if I check isNaN for lower && isNaN for upper are both not a number, this program seems to work correctly. However, if I use ||, it doesn't work as expected, as shown in my code below.

Why is this so? By using OR operator, I am saying if either upper or lower is NaN, then prompt the user to enter a valid integer. Why is it a && and not a || when only one condition needs to be true?

const getNumber = function(lower, upper) {
  if ( !isNaN(lower) || !isNaN(upper) ) {
  const number = Math.floor(Math.random() * (upper - lower + 1)) + lower;
  return number;
  } else {
  alert("Please enter a valid integer.");
  }
};

// Call the function and pass it different values
console.log( getNumber('six',5) );

Upvotes: 0

Views: 2751

Answers (2)

Mr. Hedgehog
Mr. Hedgehog

Reputation: 2885

By using OR, you are checking that at least one value should not be NaN.

let a = !isNaN(lower);
let b = !isNaN(upper);

a and b can be either true or false. When you use ||, you are telling that at least one of this values should be true. If you check Truth table, you will see that OR will be true for this combitations of a and b:

  • a == true, b == true
  • a == false, b == true
  • a == true, b == false

What you want is to check that a == true and b == true simultaneously - so you have to use AND (&&) which will evaluate to true if and only if a == true and b == true.

Upvotes: 2

T.J. Crowder
T.J. Crowder

Reputation: 1074148

It's not the ! operator that's the problem, it's ||. if ( !isNaN(lower) || !isNaN(upper) ) { says (roughly) "if lower is a number or upper is a number". But you don't wan to say "or" there, because you want them both to be numbers.

So either use use && (and):

if ( !isNaN(lower) && !isNaN(upper) ) {
// −−−−−−−−−−−−−−−−^^
    const number = Math.floor(Math.random() * (upper - lower + 1)) + lower;
    return number;
} else {
    alert("Please enter a valid integer.");
}

or reverse the content of your if and else blocks and use || without !:

if ( isNaN(lower) || isNaN(upper) ) {
    alert("Please enter a valid integer.");
} else {
    const number = Math.floor(Math.random() * (upper - lower + 1)) + lower;
    return number;
}

Side note: You're using implicit string-to-number parsing in your code. I recommend doing it on purpose. My answer here goes into your various options for parsing numbers and their pros and cons.

Upvotes: 4

Related Questions