[mercury-users] IEEE float (was: Newbie problem)

Richard A. O'Keefe ok at atlas.otago.ac.nz
Tue Jun 22 14:52:42 AEST 1999


If I may summaries Fergus Henderson's reply, at the risk of caricature:
1. Mercury's floating point arithmetic is *deliberately* **NOT**
   IEEE-compatible, even on platforms that claim (not always rightly)
   to offer IEEE support.
2. the major reason for this is the counter-intuitive behaviour of
   IEEE arithmetic (as if _anything_ about floating-point arithmetic
   were intuitive)
3. syntactically heavyweight (but probably operationally lightweight)
   support for IEEE arithmetic as a *separate* datatype is planned
4. this is acceptable because most programmers don't understand IEEE
   arithmetic anyway.

One particular detailed point I must both rebut and take the blame
for.
    it is not true that IEEE arithmetic requires X < 0.0 to quietly
    fail when X is a QNaN.  IEEE arithmetic *does* require that there
    be a {L=>T;E|G|U=>F} comparison operator, but does *NOT* require
    that it be spelled '<'.  (Not least because Fortran at the time
    spelled it .LT.)
It was I who started this by saying that "X < Y" and "X >= Y" are NOT
exhaustive because X and Y might not be comparable.  Now the IEEE 
standards *recommend* that assignment of meanings to operators, but
I don't recall that they *require* it (or can, the standard being
language-independent).

One convention that was suggested for C was to build comparison
operators from X [!][<][>][=][?] Y.
< means test succeeds if X < Y.
> means test succeeds if X > Y.
= means test succeeds if X = Y.
? means test succeeds if X and Y cannot be compared;
if that happens and ? is not in the name, it is an exception.
! means that success/failure are swapped (but not exception).
With that proposal, there would have been a difference between
X < 0.0 (succeeds *only* for negative X, exception for NaN X)
X <? 0.0 (succeeds for negative and NaN X)
X !>=? 0.0 (succeeds for negative X, fails for NaN X)

If support for IEEE arithmetic _is_ added to Mercury, some variant
of this might be a good idea.

Let's address the main points.

1.  The questions "is this intuitive" and "is this easy to reason about"
    are different.  I thought Mercury was intended to be a programming
    language for serious software engineering.  For that, we can tolerate
    a certain amount of unintuitiveness *provided* that it pays off in
    ease of reasoning, leading to more reliable code.  Now the big deal
    about IEEE arithmetic was that it was very carefully designed to be
    comparatively easy to reason about, in contrast to older and more
    ad-hoc floating-point systems.  In fact, it would not be unfair to
    say that it is one of a small handful of floating-point systems which
    *have* been designed.

    Change *any* required behaviour of the IEEE standards and the whole
    thing falls apart; it becomes just one more ad hoc implementer-or-
    hacker-oriented floating-point system with who knows what properties.
    UNLESS AND UNTIL ITS PROPERTIES ARE CAREFULLY AND EXPLICITLY SPELLED
    OUT.  For example, you can't really take out the distinction between
    +0.0 and -0.0 without also taking out +infinity and -infinity and
    the copysign() function.  You also have to worry about whether this
    has any impact on subnormal numbers (which I would be sorry to lose).
    
    I believed Zoltan when he said Mercury was an attempt to build a
    logic programming language you could offer to a software engineer
    with a straight face.  I assume therefore that someone is even now
    writing up, with the same clarity as IEEE 754 itself, what the
    Mercury-on-IEEE-hardware fp model actually is.

2.  Floating point is unintuitive no matter *what* you do to it.
    For example, I was one of the people who pointed out that the
    specification of < in Common Lisp, the Language, 1st edition
    was non-transitive, making it useless for sorting, thanks to
    the floating-point contagion rule used.  Surely *anyone* with
    schooling would find it unintuitive that there is a number X
    such that X+1.0 = X, or that (X+Y)+Z might be hugely different
    from X+(Y+Z).  It is a dangerous tool to put in the hands of
    the unwary, and to be really honest, with all IEEE 754's surprises,
    it offers no new surprises as devastating as those common to most
    floating point systems.  (Like the extremely common wobbling
    precision "bug" where X+Y != X+Y.)
    
    In short, I really don't buy "IEEE 754 surprises the unwary" as an
    argument for going out of your way to supply a different and not
    yet fully documented model, with 99% of the surprises, and those the
    more serious ones, still in it.

3.  Some IEEE support is better than none.

4.  I don't buy "programmers are not IEEE 754 experts" as an argument
    either.  The IEEE 754 standard is a very short and very clear
    little document.  One or two points are as weaselly as you would
    expect (hence the fact that simple pure ANSI C code ported from
    one IEEE machines to another and using the same sizes for its
    variables is quite likely to produce different results on the new
    machine).  But on the whole, it is by *far* one of the easiest
    computing documents around to understand, *vastly* simpler than
    HTML (which runs to hundreds of pages) or, dare I say it, Mercury
    itself.

    The documentation of Mercury is sufficiently bulky that a brief
    but adequate explanation of IEEE 754 floating point arithmetic would
    be a scarcely detectable enlargement.  In fact, producing such an
    explanation would be rather easier than documenting whatever
    Mercury's new model is.

One thing that the Quintus people learned the hard way (starting from
C Prolog experence) was that plugging in your own ad hoc floating point
model is deservedly unpopular with paying customers, who want to pass
reasonable data safely through the foreign interface in both directions
and who *don't* want what is essentially the same expression giving
different results in C++ and Prolog/Mercury/whatever.  Having to deal
with two models makes life *harder* for them, not easier.

In fact, it is precisely *BECAUSE* many of the people who use Mercury
will not be expert numerical analysts that Mercury ought *NOT* to have
a default floating-point model different from the underlying system.
(It would be rather nice if FM and ZM were available via a Mercury
interface, but they would be *non*default.)  Why?  Because on the
occasions when they *do* have to write numeric code in Mercury, they
may translate stuff taken from a book or journal paper, and will not
have the skills needed to work out
 - which bits depend on what IEEE properties
 - what to do instead.


--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the users mailing list