0

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) );

4
  • NaN does not check if a string is a number. You have to parse it first. Then, the parsing result may be NaN if it could not be parsed Commented Mar 13, 2021 at 10:29
  • console.log(isNaN("six"), isNaN(5)) Commented Mar 13, 2021 at 10:29
  • 1
    @Random - isNaN will use implicit string->number parsing if you pass it a string. (In contrast, Number.isNaN won't.) Commented Mar 13, 2021 at 10:29
  • If you want to use OR you need to remove the NOT - Using isNan here is somewhat of a double negative situation, so you either want x AND y are both NOT isNan, or x OR y isNan Commented Mar 13, 2021 at 10:30

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.