compare on Double

Isaac Dupree isaacdupree at charter.net
Sat Mar 24 09:25:49 EDT 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ketil Malde wrote:
> Neil Mitchell wrote:
>> I'm still not happy with adding more incompleteness into something
>> that intuitively feels safe - compare is pretty benign. Having a crash
>> on division is something that does appeal to me more.
> Are you suggesting that 0.0/0.0 should crash also?  I'm no expert, but
> think returning a NaN is according to the floating point standard (IEEE
> 754), and I'm not convinced Haskell should break that.  If you use
> floating point, you need to know the pitfalls anyway.  Maybe comparing
> NaNs should give random results? :-)

:-) non-referential-transparency always seems attractive for silly cases
like this, doesn't it

> The bad thing is that comparison can hide the NaNs (for arithmetic, NaNs
> will be contagious, so you'll likely get a NaN riddled output).

Yes - non-signalling NaN in a pure language like Haskell is similar to
_|_, with the biggest difference being that you can check whether a
value is NaN/Inf/-Inf (in pure code). (where that _|_ could specifically
be some sort of NaN imprecise exception). Of course _|_ is still the
least fixed point, e.g. infinity = infinity + 1 won't give you an
Infinity.  So, do we want _some_ computations to be ill-defined in a
well-behaved way by using the IEEE NaN bit-patterns as we do?

The FiniteDouble wrapper seem like an interesting approach.  If you
don't want the CPU to do all that checking of intermediate values... but
that can be optimized away anyway.  What is a use case for code that
wants to check whether a value is NaN?  Perhaps the positive and
negative infinities are more commonly worth being non-_|_ since they
don't break the total order and can be generated by mere overflow
(2.0^(2^1000) anyone?).  Furthermore, since with a large finite double
subtracting 1 does not reduce the number, is infinity that much weirder?

Another approach I tried with a type for integers including +-Infinity
and NaN was to just arbitrarily make NaN be less than all other values,
including -Infinity, and it is a total order (other values are greater
than NaN, and NaN is equal to itself). That way it can be stored in Maps
and such. (I later decided I didn't really like the mathematically
not-very-sensible-ness of those values existing, for my use case, but
that's a different matter.)

Does anyone else think (==) should always be reflexive for any type it's
defined for? (i.e. for all n, (n==n)==True) (except when its arguments
contain _|_, in which case (==) might inevitably result in _|_).  The
class "RealFloat" in the prelude already provides isNaN, isInfinite...
which are more sensible than checking for NaN with not(n==n) in Haskell


Isaac
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGBSbdHgcxvIWYTTURAu1RAJ44waLiwdfIklbUmFyXW1CwVI2CEwCgzRBF
4wU29F5OIKCdWyK41crSX3s=
=usWc
-----END PGP SIGNATURE-----


More information about the Libraries mailing list