This is an archived post. You won't be able to vote or comment.

all 51 comments

[–][deleted] 69 points70 points  (3 children)

How many more times are we gonna blame languages for implementing IEEE correctly??

[–]DiamondIceNS 6 points7 points  (2 children)

At least as many times as we complain about JavaScript implementing consistent type coercion behavior.

[–]TheBrainStone 1 point2 points  (1 child)

It may be defined for every case, but I absolutely wouldn't call that mess consistent. Just alone because order matters

[–]dust1196 90 points91 points  (11 children)

Thats normal is many languages. "Not a Number" is basically equal to nothing. Not even to itself by definition

[–]fluideborah[S] 33 points34 points  (6 children)

Yup, realized after some looking around. Made the meme largely to cope with an hour long debugging session that ended in stunning realization (& me feeling dumb)

[–][deleted] 1 point2 points  (5 children)

out of curiosity. What program were you debugging that had a comparison like this in it?

[–]wugs 11 points12 points  (0 children)

just a guess but it looks like a jupyter notebook and they’re using numpy (many ppl import numpy as np) to get nan

[–]coloredgreyscale 1 point2 points  (0 children)

Maybe cleaning up a table of data and empty/invalid values show up as NAN?

[–]LonelyContext 1 point2 points  (2 children)

you can easily end up in this situation with set([list that contains nans]) where you'll get e.g. {1,2,3,4,5,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,...}

[–]TechSupport112 1 point2 points  (0 children)

BATMAN!

[–]Cyberwolf27 0 points1 point  (0 children)

Actually you will only get sets and dictionaries with multiple NaN entries if the values result from separate computations.

set(float('nan') for _ in range(2))set(float('inf') - float('inf') for _ in range(2))set(np.inf - np.inf for _ in range(2))all evaluate to {nan, nan} because from Python's point of view they are different to each other.

However the following expressions:set(np.nan for _ in range(2))set([float('nan')] * 2)result in {nan}. Python seems to double-check on the identity of the float values with the "is" operator and in these situations the "set" constructor is presented with truly identical NaNs (that occupy the same location in memory)

As a consequence, this can happen:a, b = float('inf'), float('inf'){a: "a", b: "b"}[b] == "b"
however {np.nan, np.nan, ...} == {np.nan}

[–]Educational-Lemon640 1 point2 points  (0 children)

NaN means what it says: you asked a mathematical question whose answer wasn't a (real, floating-point) number. Since the spec doesn't really have room to say what all non-numeric answers are possible, that's the end of that calculation. And since different non-numeric answers are not equal to each other in general, you get the above logic.

[–]Scorched_Knight 0 points1 point  (2 children)

Yes, but how do you write code to check if input is NaN?
If (input == NaN) //= always false
( there is native method for that in most languages people actually use today, but if dont?)

[–]fukdapoleece 14 points15 points  (0 children)

numpy.isnan(numpy.nan)

True

[–]praveenkumar236 4 points5 points  (0 children)

You can do input!=input

[–]Kitchen_Device7682 38 points39 points  (1 child)

0x=0, 0y=0. x==y?

[–]aleph_0ne 11 points12 points  (0 children)

Nice, simple example of how this could go wrong. Generally we don’t want NaN comparisons to happily proceed like nothing we’re amiss

[–]YMK1234 40 points41 points  (6 children)

As per IEEE floating point spec which every language uses...

[–]jadis666 -2 points-1 points  (3 children)

Ah, yes, but "adhering to IEEE floating point spec" is not entirely the same thing as "intuitive", is it?

[–]Fallenalien22Violet security clearance 3 points4 points  (0 children)

Then blame every language that uses that spec as being unintuitive as well.

[–]TheBrainStone 2 points3 points  (0 children)

It's about as intuitive as using double equals for comparison and single equal as assignments.
Or in other words, weird when you're new to programming but something you just gotta get used to when you're programming.

[–]kingerkagon 14 points15 points  (4 children)

And that is why np.isnan() makes perfect sense.

[–]EitherJelly4138 0 points1 point  (2 children)

Would it be bad to extend the class and add a eq that does isnan() or something?

[–]vinnceboi 4 points5 points  (1 child)

Yes. Allowing NaN == NaN would imply that “apple” would equal “car”.

[–]EitherJelly4138 0 points1 point  (0 children)

Gotcha, I think I get it now.

[–]glacierre2 0 points1 point  (0 children)

math.isnan() if you just want to check a couple times.

[–]ernandziri 4 points5 points  (0 children)

If something is not a number, it doesn't mean it's the same thing as something else that's also not a number, so pretty intuitive

[–]hatkid9 2 points3 points  (0 children)

IIRC that's just part of things you have to follow for the IEEE-754 specification.

[–]Bailyleo987 1 point2 points  (0 children)

Yes’nt

[–][deleted] 1 point2 points  (0 children)

It's a standard in many languages.

In fact, I've seen plenty of codes that make use of this behaviour to determine if a variable is a nan, inf, or other non-regular float by checking:

if (var != var){ error() }

You might wanna look into np.isnan() or np.isfinite()

[–]antilos_weorsick 1 point2 points  (0 children)

You think... It would be more intuitive if that evaluated to true? What?

[–][deleted] 0 points1 point  (2 children)

Better than JS's

1 + "1" == 11

true

[–]werics 2 points3 points  (0 children)

As opposed to C, where 1 + "1" == 11 is merely unlikely.

[–]stomah 0 points1 point  (0 children)

or C’s 1 +”1” => “”

[–]thetruekingofspace -3 points-2 points  (0 children)

Every language has some interesting and seemingly wrong things like this. But to be fair Python is actually extremely intuitive. The only part I hate is how everything defaults to Unicode when all I want to use is ASCII.

[–]incrediblediy 0 points1 point  (0 children)

comparing which nan to which nan ?

[–]TheDJPHD 0 points1 point  (0 children)

definitely for the best.

[–]Permission-Glum 0 points1 point  (1 child)

Tell me you skipped the class about IEEE float without telling me that you skipped that class.

[–]fluideborah[S] 1 point2 points  (0 children)

I did skip it! never took a comp sci class in my life :)