7 ms·
> Instead we get some bizarro-world where where the type of NaN (“Not a Number”) is number, where NaN !== NaN*, and a chart like this exists for something as si
by DiThi 12y ago
> Instead we get some bizarro-world where where the type of NaN (“Not a Number”) is number, where NaN !== NaN*, and a chart like this exists for something as simple as comparing two values.
That's the definition of NaN in virtually any programming language with floating point numbers. And the comparison table makes sense with the rule "when types are incompatible, both are casted to strings". Just use === instead of ==, which is only really useful for comparing against null/undefined.
- andrewstuart2 12y agoAlso in logic. Not something is never equal to not the same thing. A bird is not a rock. A computer is also not a rock. Clearly not equal to each other.
- kazinator 12y agoThe stupid thing about IEEE NaN is that it's not equal to itself! If variable x holds a NaN, then (x == x) is false. This violates: http://en.wikipedia.org/wiki/Law_of_identity http://en.wikipedia.org/wiki/Law_of_identity If (x == x) tests false, then it asserts that x is not itself, which is logically preposterous. ANSI Common Lisp has a bit of this problem in it too, but it's not required; it is there for some weird historic implementations. That is to say, if x holds a number like 1, then (eq x x) is not required. (But in sane implementations it does yield t; and it yields t even if x is a bignum, because (eq x x) is given the same object as two arguments. Two separately computed bignums of equal value will likely, of course, not be eq. How this can be explained is that eq tests "implementation identity", and somehow different instances of a number are treated as different implementations. Argument passing is by value, and the two reductions of the expression x in (eq x x) to a value somehow produce a different implementation of the value. This rationale is unrelated to IEEE NaN-s, though.
- pwnna 12y agoDon't quote me on this, but I recall the rational for NaN is because NaN is typically the result of a division by 0. Divisions by 0 can be thought of as infinity (for the sake of this explanation, but mathematicians will cringe), but it is not any particular infinity. In the sense that x / 0 does not necessarily have to equal y / 0. For that definition, the result of a division by 0, NaN, must not equal itself. You can use `isNaN`, tho.
- dbaupp 12y agoIEEE division by zero gives positive (or negative) infinity (with the sign determined by the sign of the zero). NaN crops up with e.g. sqrt(-1) and infinity - infinity for which there is no way to define a sane answer.
- kazinator 12y agoDetermining positive or negative infinity from the "sign of the zero" is not sane to begin with. Zero has no sign in mathematics. It's just a representational accident in floating-point: there is a one bit wide field for sign, and for the sake of uniformity, representations of zero have that field too. Treating these as different is dumb; they are just different spellings of the same number in a bitwise notation. To drive the point home, this is somewhat like making 0xF different from 15.
- bsder 12y ago> Zero has no sign in mathematics. Not wrong, but zero having a sign is useful for several complex plane algorithms--it's not just an accident. As a general rule, anything that is in IEEE 754 (or 854) has a damn good reason for being there, and you had best take some time to understand it or risk looking stupid. A lot of hardware people screamed about a lot of the obnoxious software crap in IEEE 754, so, if something survived and made it into the standard, it had an initial reason for being there even if that reason has gone away with time/the advance of knowledge/Moore's Law. The original designer's commentary about it is: William Kahan, "Branch Cuts for Complex Elementary Functions, or Much Ado About Nothing's Sign Bit", in The State of the Art in Numerical Analysis (eds. Iserles and Powell), Clarendon Press, Oxford, 1987.
- mbrubeck 12y agoYes. The research culture that produced Haskell, for example, is far from the "shipping culture" that produced JavaScript 1.0, and yet: > let x = 0/0 > x NaN > x == x False > :type x x :: Double (and yes, Double is an instance of the Num type class) The author programs in C++ and D. I wonder if he knows the value of (NaN == NaN) in those languages?
- thinkling 12y agoI think the author just picked an awkward example. The real point is the existence of that table of weird (non)equalities and (non)truthinesses in JS [1]. [1] https://dorey.github.io/JavaScript-Equality-Table/ https://dorey.github.io/JavaScript-Equality-Table/
- flomo 12y agoI cracked up over the famous NaNNaNNaNNaN Batman presentation. But, IMO that table is very predictable for a 'dynamic' language, for the normal use-cases. It only gets strange on the outer edges with oddball arrays and objects. But, if you have code which compares one-element arrays with strings, you have bigger problems than javascript. I can't recall seeing any serious comparison Batman-style bug. Hypothetically, that kind of stuff wouldn't even be a logic bug, but a design issue that was allowed by the dynamic type system. Solution: don't bitch about Javascript, use something else.
- romaniv 12y agoNaN behavior might actually be appropriate in Haskell. I don't know enough about it to comment. But it is not helpful in JavaScript. Part of the problem is that in JS you can get NaN in a variety of different ways that do not involve mathematics. And that all numbers can be floats (whereas in other languages we have integers). And that NaN can be silently propagated and morphed in in a more complex expressions.
- deleted 12y ago[deleted]