[BUG] Float NaN's

Richard A. O'Keefe ok at cs.otago.ac.nz
Tue Sep 14 01:51:18 UTC 2004


Chris Muller <afunkyobject at yahoo.com> wrote:
	(Set with: Float nan) includes: Float nan    "false"
	
	(Dictionary at: Float nan put: 'NaN'; yourself) printString   "boom"
	
	Is this a bug?
	
It's certainly an interesting question.
Set and Dictionary assume that (x = x) always answers true.
However, the IEEE 754 and IEEE 854 standards (and the IEC revision,
and the draft revision of IEEE 754 that I believe is still in progress)
is quite explicit that if x is a NaN, x does NOT equal itself.
In fact, that's one way to test whether something is a NaN:

    Float>>isNaN
        ^self ~= self

I suggest that the behaviour of Set here is the simplest behaviour which
is consistent with both Set (find an element that is #= to the argument)
and IEEE 754 (NaNs are not equal to themselves).

(Dictionary at: Float nan put: 'NaN') is an attempt to mess with
the Dictionary class itself.  Since Dictionary is not an indexable
object (Dictionary class isVariable => false) the primitive fails.

(Dictionary new) at: Float nan put: 'NAN'; printString

pops up an 'Error: key not found' due to Dictionary>>at: Float nan.

One would have expected that printing a Dictionary containing n
bindings would be O(n) + the cost of printing the keys and the values.
It isn't.  Thanks to the use of #keysSortedSafely, it's O(n.lg n) + ...
And #keysSortedSafely has its own problems: it is not clear to me that
the sort order it uses would be consistent in the absence of NaNs, but
it's quite clear that it's NOT consistent in the presence of NaNs.
What I'm getting at here is that a good sorting algorith which has
found that x <= y and y <= z will often not bother to check whether
x <= z, because it "knows" that it is.  Well,
    NaN < 2.0 is false, so 2.0 <= NaN (x <= y)
    1.0 < NaN is false, so NaN <= 1.0 (y <= z)
But is it true that 2.0 <= 1.0 (x <= z)?
If it comes to that,
    1.0 < NaN is false, NaN < 1.0 is false, but NaN is not equal to 1.0
    
Does anyone know why #keysSortedSafely is used?  Who is 'sma'?
Dictionary printing would be faster and safer without it.
Set printing doesn't run into this problem because it doesn't sort.
Why sort Dictionaries but not Sets?

For what it's worth, in Ambrai Smalltalk
   |z n s|
   z := 0.0.
   n := z/z.
   s := Set with: n.
   s includes: n
=> false   
and
    |z n d|
    z := 0.0.
    n := z/z.
    d := Dictionary new.
    d at: n put: 'NaN'.
    d printString
=> 'Dictionary(NaN->(''NaN''))'
and
    d at: n
throws a 'key not found' ErrorMessage.



More information about the Squeak-dev mailing list