3

My first programming language is python. And recently I'm learning C and javascript.
In javascript, there is a design which confused me a lot, default the function isNaN.

Put aside its weird exceptions in specification(Which is hard to find), such as isNaN(""), isNaN(["22"]).
The more frustrating thing is that the result of isNaN consumes my thinking energy, though a tiny bit every time, before I established an intuition about it.(Which requires quite a bit of efforts)

But man, we are lazy. And this design does not follow the human instinct.
The examples below records how my brain works when seeing the two types of expressions in python and javascript:

isNaN(n)
false

# THOUGHTS:
# The result of isNaN(n) is false, what does it mean?
# it means n is not a number is false.
# OK, let me think for a while..
# So, I assume it is a number(with hesitation)


type(n) == int
False

# THOUGHTS:
# type(n) == int returns False, what does it mean?
# So it tells us that `the type of n equals int` is false
# So the type of n is not equal to int!
# I think n is not a int.

I think human beings have a tendency to assume everything is True at first.
Thus multiple negative levels on statement will increase our recognition cost.
On this sight of view, the design of isNaN is a bad one, and isN(isNumber) is a better solution for human understanding.
But as a sceptic, I'm wondering there may have some background story about this design, to achieving a important functionality, the author chosen this design as a tradeoff? Was there a good reason, or is this just a design deficiency(in the sense of human friendly)?

2

3 Answers 3

12

The purpose of isNaN is not to check if a value is nummeric or not. It actual purpose is to check if a floating point number has the special value of NaN. The special NaN value is assigned to the results of mathematically impossible operations, like dividing 0/0 or converting an alphabetic string to a number.

However, when you try to use isNaN on a value which is not a floating-point number, Javascript first tries to convert it to a number and then checks if that number has the special NaN value. To make matters more confusing, undefined is also treated as NaN by Javascript, so when the value can not be converted to a number, it is considered NaN.

To protect yourself from headache, only use isNaN when you are really looking for the floating point NaN value.

When you want to know if a variable is a number, use typeof variable == 'number' (the value of NaN is also of type number, by the way). When you want to know if a string can be converted to a number, use isNaN(Number(variable)).

2
  • only use isNaN when you know the argument is a number, more like. Excluding the special case later. Oct 19, 2015 at 11:51
  • 2
    Good answer, but it contains one imprecision: There is not just one special NaN, but a whole plethora of different values that are treated as NaNs. Especially there is a distinction between signaling and quiet NaNs. However, these are hardware specifics, all languages treat all NaNs exactly the same, so your answer is close enough; I would just recommend to speak of NaNs as plural not as "the special NaN value". Oct 19, 2015 at 12:35
10

"Not a Number" (NaN) has its roots in something much larger than JavaScript. You have to go back to 1985 and the IEEE-754 standard for floating point mathematics to understand it. NaNs occur in several ways during mathematical operations (e.g., division of 0 by 0), and isNaN() functions are intended to determine when a putative number is in fact not a number. JavaScript's particular implementation of isNaN() is, unfortunately, a byproduct of its willingness to treat values that aren't obviously numbers as numbers.

1
  • 6
    Nitpick: Division by 0 generally results in +/- infinity. Operations that produce NaN include 0/0 and sqrt(negativeNumber).
    – user7043
    Oct 19, 2015 at 11:44
3

Javascript's isNaN is a bit of a botched job on the concept of what Not-A-Number represents. The intent of NaN is to represent indeterminate numerical forms such as 0/0 or ∞/∞, and to represent the result of out-of-range numerical calculations such as sqrt(-1) and asin(2). The ES6 release of ECMAScript addresses this issue by adding the Number.isNaN function. This new function doesn't coerce a non-numeric value into a numeric value before testing. The result of calling Number.isNaN with a non-numeric value is false. This makes it clearer that the purpose of isNaN is to test for a numerical value that does not represent a numerical value.

There's a funny thing about NaNs: Arithmetic comparisons that involves a NaN must always return false. Even x == x (or x===x in javascript) will return false in the special case that x is a NaN. Anything but a NaN will compare equal to itself, yielding a cryptic way of testing whether something is a NaN. Using isNaN(x) does a much better job of conveying intent than does !(x==x).

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.