[Python-Dev] Rich comparisons (original) (raw)

Tim Peters tim.one at comcast.net
Tue Mar 30 00:00:20 EST 2004


[Edward Loper]

This means that 'nan' is no longer a well-behaved dictionary key:

>>> x = {float('nan'):0} >>> x[float('nan')] = 1 >>> print x {nan: 0, nan: 1}

Whatever happened there is a platform accident. For example, not even the float('nan') part is portable. On Python 2.3 on Windows, your example already works that way (here just changed to spell NaN in a way that works on Windows):

inf = 1e3000 x = {} x[inf - inf] = 0 x[inf - inf] = 1 print x {-1.#IND: 0, -1.#IND: 1}

Even worse, we get different behavior if we use the "same copy" of nan:

>>> nan = float('nan') >>> x = {nan:0} >>> x[nan] = 1 >>> print x {nan: 1}

dict lookup does assume that "key1 is key2" implies "key1 == key2", so at least that one will work the same way across platforms.

[Michael Hudson]

Gah. Still, I think this is more a theoretical objection than anything else?

I do.

BTW, with 2.3 on OS X:

>>> {1e3000/1e3000:1}[0] 1 >>> {0:2}[1e3000/1e3000] 2 So your 'no longer' isn't really valid :-)

If we really want nan==nan to be false, then it seems like we have to say that nan is unhashable.

Python doesn't have access to a portable way (at the C level) to determine whether something is a NaN, and the hash value of a NaN follows from whatever accidental bits the platform C modf(NaN, &intpart) returns.

I'm also disturbed by the fact that cmp() has something different to say about their equality:

>>> cmp(float('nan'), float('nan')) 0

Well, yah. cmp() assumes a total ordering. If there just isn't one, what can we do?

If we could recognize it was a NaN, my preference would be to raise an exception. I was told that GNU sort arranges to make NaNs look "less than" all non-NaN floats, which is a way to make a total ordering -- kinda. Not all NaNs contain the same bits, and depending on other platform accidents "the other bits" in a NaN may or may not have significance to the platform C and its libraries.

I have at no point claimed that I have given Python 2.4 a coherent ieee 754 floating point story.

Ya, but I keep telling people you claim that .

All I have tried to do is /reduce/ the level of surprise knocking around, and I think I've succeeded.

Making

x relop y

return the same thing as the platform C does reduce the surprise -- at least for those who aren't surprised by their platform C's behavior.

If someone (not me!) has the time and energy to do a 'proper job' (and I'd expect working out what that means to be the hard part), then you have my support and pre-emptive thanks.

I don't believe it will happen until all the major C compilers support the (still optional!) 754 gimmicks in C99 -- or Python is rewritten in some other language that supports them. Before then, we'd need a small army of people expert in the intersection of their platform C and the 754 standard, to produce piles of #ifdef'ed platform-specific implementation code. That's doable, but unlikely.

tomorrow-is-usually-like-yesterday-ly y'rs - tim



More information about the Python-Dev mailing list