Squeak SmalltalkJoker Squeak Smalltalk : Language : prevnext Float nan Not a Number IEEE

>   (Dictionary new at: Float nan put: 'nan'; yourself) printString
>
> Also, I'm interested in your commentary on the first example too..
>
>   (Set with: Float nan) includes: Float nan    "false"
>
> do you think these are bugs?

No, I think these are not bugs. First, this has nothing to do with 
Sets and Dictionaries, it is a property of Float. First, try this: 
Float nan = Float nan You obtain false. At first sight, this is a 
surprise, but it is possible to defend this result with good reasons. 
Look at this:

1.0e200 tan = 1.0e200 tan gives false and

1.0e200 tan = 1.0e200 sin gives also false.

This last example is the key to a better understanding of the 
properties of NaNs. A NaN represents the result of a computation that 
can not be represented as a Float value.

As we can certainly not say that

1.0e200 sin   and  1.0e200 tan are equal,

it is best to assume that two NaNs are never equal. (Database 
progammers will remember similar rules for NULL values. Two NULL 
values are never considered to be equal, simply because the represent 
unknown entities).

From the Intel documentation of instruction FCOm (Float COMpare)

>>If either operand is a NaN or is in an unsupported
>>format, an invalid-arithmeticoperand exception (#IA)
>>is raised and, if the exception is masked, the condition
>>flags are set to "unordered." If the invalid-arithmetic-
>>operand exception is unmasked, the condition code
>>flags are not set.

This means that NaNs are never considered to be equal. Note also that 
NaN is not represented by a single bit pattern: There are a lot of 
different representations of NaN: A NaN is an invalid floating-point 
result that has all ones in the exponent with a significand that is 
not all zeros.

Hope this helps, Boris
----------
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.

O'Keefe

-----

I remember researching this to try and get VW up to date w.r.t. ieee fp 
math and learning something interesting things about NAN. It is the 
singularity event horizon of fp math. Any math you do with it will turn 
into a NAN. Even +/-infs. All roads lead to NAN. And when you get 
there, it refuses to be "truth"ful about anything. It is not = to 
itself or anything else for that matter. It gets better. It's not 
greater or less than itself. Or anything else. Greater than or equal 
and the flip don't work either. The thing is the "false" hole.
 
Travis Griggs


---

 Is it true, that we could have
   aNaN == aNaN & (aNaN ~= aNaN) -> true
 (identity but not equality) here?
 
So try it in a Workspace:
 x := Float nan.
 (x == x) & (x ~= x)
=> true
So yes, that does actually happen.  And there are 2*(2**53-1) bit patterns
that count as IEEE Not-a-Numbers.  (Sign field can be + or -, exponent
field must be 0, significand must not be 0 because that would be Infinity.)

RAOK