caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Xavier Leroy <Xavier.Leroy@inria.fr>
To: Christian Lindig <lindig@pauillac.inria.fr>,
	Caml Mailing List <caml-list@inria.fr>,
	George Russell <ger@informatik.uni-bremen.de>,
	Archisman Rudra <archi@mosaic.mrl.nyu.edu>
Subject: Re: NaN Test in OCaml
Date: Thu, 1 Feb 2001 15:41:56 +0100	[thread overview]
Message-ID: <20010201154156.B30653@pauillac.inria.fr> (raw)
In-Reply-To: <20010131140503.D2418@lakeland.eecs.harvard.edu>; from lindig@eecs.harvard.edu on Wed, Jan 31, 2001 at 02:05:03PM -0500

> George Russell <ger@informatik.uni-bremen.de> has suggested on
> comp.lang.ml the following test to find out whether a float is NaN:
>         x is not a NaN <=> (x = x)
> Doing this leads to interesting results with OCaml 3.0:
>     # let nan x = not (x = x);;
>     val nan : 'a -> bool = <fun>
>     # nan (1.0 /. 0.0);;
>     - : bool = false            (* correct *)
>     # nan (0.0 /. 0.0);;
>     - : bool = false            (* should be true *)
> The following definition of nan uses a type annotation and has a
> different result:
>     # let nan (x:float) = not (x = x);;
>     val nan : float -> bool = <fun>
>     # nan (0.0 /. 0.0);;
>     - : bool = true             (* correct *)
>     # nan (1.0 /. 0.0);;
>     - : bool = false            (* correct *)
> Is this a bug or a feature?

It is a bug, more exactly a design error in generic comparisons.

The difference between the two examples is that in the second case
(with the type constraint), the compiler performs type-specialization
on the "=" predicate, turning it into the equality predicate over
floating-point numbers.  This predicate works as specified in IEEE,
in particular NaN is not equal to NaN.

In the first case, no type information is available, so generic
equality is called.  Generic equality is defined in terms of the
"compare" polymorphic comparison function:

        let (=) a b = (compare a b = 0)

and "compare" implements a total ordering relation: either its
arguments a and b are equal, or a is smaller than b, or a is bigger
than b.

But of course IEEE floats are not totally ordered, due to NaN...  
So, rather arbitrarily, "compare NaN NaN" returns 0 -- but any other
return value would be equally wrong!

What is needed is to revamp the polymorphic comparison function so
that it has four possible outcomes: equal, less than, greater than,
and unordered.  "compare" would raise an exception in the "unordered"
case, but generic comparisons (=, <=, <, >=, >) would return "false".
I haven't looked at how to implement this behavior yet, though.

To come back to Archisman's initial question, I'm considering adding an
"fpclassify" function similar to that of ISO C9X, to determine whether
a float is NaN, infinite, zero, exact or denormal.  That should avoid
the confusing "x <> x" test.

- Xavier Leroy



      parent reply	other threads:[~2001-02-02 15:24 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-01-31 19:05 Christian Lindig
2001-02-01  9:19 ` David Mentre
2001-02-01  9:58 ` Andreas Rossberg
2001-02-01 14:41 ` Xavier Leroy [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20010201154156.B30653@pauillac.inria.fr \
    --to=xavier.leroy@inria.fr \
    --cc=archi@mosaic.mrl.nyu.edu \
    --cc=caml-list@inria.fr \
    --cc=ger@informatik.uni-bremen.de \
    --cc=lindig@pauillac.inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).