On to Hydro

Tyler Close tjclose@yahoo.com
Fri, 18 Aug 2000 09:02:18 -0400


Markm wrote:
> At 01:06 PM 8/17/00 , Tyler Close wrote:
> >you'll have to upgrade the "<" operator to at least strict weak
> >ordering, though I'll push for total ordering.
> >
> >I think the solution might be that we don't provide any 'automatic'
> >comparison operators, and just map them all into method names.
> >
> >Operator   Method     Ordering
> >--------   ------     ---------
> >    <       before     total or strict weak
> >    <=      within     partial
> >    >       after      total or strict weak
> >    >=      includes   partial
>
> Are you proposing that "<" and ">" be defined in terms of
> one order while
> "<=" and ">=" be defined in terms of a different one?  In
> you proposal,
> would the following equations no longer hold:
>
> (a < b) == ((a <= b) && !(a >= b))
> (a <= b) == ((a < b) || (a >= b))

If the ordering of "a" was only partial, then both expressions would
result in a NoSuchMethodException being thrown by the "a < b" parts.
If the ordering of "a" was total, then the equations would hold. Types
with only a partial ordering do not implement "<" or ">".

It would have to be part of the contract of the comparison operators
that if you implement "<" or ">", they have to be consistent with your
implementation of "<=" and ">=".

> As to total vs strict weak; if I understand the definitions
> correctly, it is
> equivalent to asking whether we can dispense with "<=>" and
> just use "=="
> instead.  I hate to use IEEE floating point again, but what
> about -0.0?  In E,
>
>      ? -0.0 == 0.0
>      # value: false
>
>      ? -0.0 <=> 0.0
>      # value: true

It looks like everyone is all over the map on these issues and no one
has a consistent way of dealing with it. From the JDK1.3 Javadoc for
Double.equals():

---------------begin excerpt-------------------------------

Compares this object against the specified object. The result is true
if and only if the argument is not null and is a Double object that
represents a double that has the identical bit pattern to the bit
pattern of the double represented by this object. For this purpose,
two double values are considered to be the same if and only if the
method doubleToLongBits(double) returns the same long value when
applied to each.
Note that in most cases, for two instances of class Double, d1 and d2,
the value of d1.equals(d2) is true if and only if

   d1.doubleValue() == d2.doubleValue()

also has the value true. However, there are two exceptions:

If d1 and d2 both represent Double.NaN, then the equals method returns
true, even though Double.NaN==Double.NaN has the value false.
If d1 represents +0.0 while d2 represents -0.0, or vice versa, the
equal test has the value false, even though +0.0==-0.0 has the value
true. This allows hashtables to operate properly.

---------------end excerpt-------------------------------

So there are two issues raised by this excerpt: equality of NaN and
your +0.0 == -0.0.

Equality of NaN
---------------
For this, I'll take a suggestion from the William Kahan paper that Hal
pointed us to. (Thank you Hal!)

"If all goes well, infinite intermediate results will turn quietly
into correct finite final results that way. If all does not go well,
Infinity will turn into NaN and signal INVALID."

It sounds to me as if NaN was never intended to be a stable final
result and that it is perfectly reasonable to throw an exception if a
calculation results in NaN. Following that strategy would linearize
the field of doubles, getting rid of both the comparison issue and the
equality issue.

+0.0 == -0.0
------------
Again based on reading of the William Kahan paper, I have the
impression that +0.0 and -0.0 are actually different numbers with
different meanings, and are not equal or equivalent. I believe both
the answer that E gives for -0.0 <=> 0.0, and that Java gives for
+0.0==-0.0, are wrong. The behaviour of Double.equals() is the correct
answer.

> 0.0 and -0.0 denote the same real number, and so are
> numerically equivalent.

They do not denote the same real number. They are different
numbers. -0.0 < 0.0 should be true. This behaviour agrees with that
specified for Double.compareTo in the JDK1.3 documentation.

> But they are not computationally equivalent.  In E
> terminology, the are "as
> big" or "the same magnitude", but they are not "the same".

The Kahan paper indicates that they are not computationally
equivalent.

Tyler


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com