On 21-Jan-1999, Mark P Jones <[EMAIL PROTECTED]> wrote:
> Hi Fergus,
> 
> Thanks for your bug report:
> 
> | For hugs-1.4, the following query
> | 
> |     hugs> let x::Double; x = (1.0e100 - 1.0e100) in x == x
> | 
> | results in the answer "False" on a sparc-sun-solaris2.5 system.
> | It also results in the hugs interpreter crashing due to 
> | "Unexpected signal"
> | on a dec-alpha-osf3.2 system.  These should probably both be
> | considered bugs.
> 
> And on an Intel machine I get yet another different behaviour: True!
> 
> You're right that it's a problem, but I don't know how to address it.
> I do remember looking into this a few years ago and concluding that
> there was no way to handle it nicely with the range of different C
> compilers that `mattered to me' at the time.  Times, and compilers,
> have changed however.  If you've found a good way to deal with this
> in your Mercury implementation (or if anybody else has a good
> solution), then I'd be very interested to hear about it!
>
> | The other bug is that the documentation doesn't say what should
> | happen in the case of floating point overflow.
> 
> I guess we must defer to the Haskell manual for that?  Whatever it
> says goes, and if it doesn't say anything, then anything goes!
> (Or is that: if it says nothing, then nothing goes? :-)

If the Haskell report doesn't say what the semantics of the language are
(and in this case indeed it doesn't), then that is a bug in the Haskell
report, IMHO.  It would be OK for the Haskell report to leave the semantics
unspecified, so long as it explicitly says so, but simply leaving
things unsaid leads to too much ambiguity.

Also, IMHO the Haskell report should specify that "==" must be an
equivalence relation, at least for the built-in types defined
in the standard prelude and the standard library.

There is a difficulty with making "==" an equivalence relation for
Float and Double: the IEEE standard says that two NaNs should not
compare equal.  There are at least two ways around this: (1) ensure that
no NaNs are ever produced, or (2) define "==" in Hugs as something
other than "==" in C, e.g. by comparing the bits, and provide some
other operator, e.g. "ieee_equal", for the IEEE equality test.
I think (1) is the better choice.  A portable way to ensure this
is to test the result of each floating point computation to
see if the result is a NaN, using e.g.

        #define is_nan(x) (!((x) == (x)))

If the result is indeed a NaN, then Hugs could raise a Haskell
exception (using the new exception throwing/handling scheme).

That would fix the problem with the above test case returning "False"
on a sparc-sun-solaris2.5 system.

More efficient solutions are available on many systems;
these could be selectively enabled using autoconf or similar.
But I don't think efficiency is such a big concern for Hugs, is it?

Regarding the problem with the Hugs interpreter crashing,
I think on many systems you should be able to use signal() or
sigaction() to catch SIGFPE, and then call longjmp() from the
signal handler to recover.  That isn't guaranteed by the C
standard, but I think it is likely to work on most systems.

P.S. The current Mercury implementation doesn't deal with these
issues properly.  We do however at least document what the intended
behaviour is, and how the current implementation differs from that.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "Binaries may die
WWW: <http://www.cs.mu.oz.au/~fjh>  |   but source code lives forever"
PGP: finger [EMAIL PROTECTED]        |     -- leaked Microsoft memo.

Reply via email to