# benchmarking Poly/ML & floating point

Matthew Fluet fluet@CS.Cornell.EDU
Mon, 11 Sep 2000 18:00:53 -0400 (EDT)

> I now believe I understand what is going on.  In C, x != y is exactly equivalent
> to !(x == y).  Thus, the definitions of Real_nequal and Real_equal in
> mlton-lib.h are correct.  Although there's still no reason I can see for keep
> around the primitive Real_nequal, since it is just not o Real.==.  As to

Well, there is the efficiency question.  Real_equal is implemented by
and-ing and comparing th floating point status word and then doing a setz.
So, Real_nequal is done exactly the same way, except with a setnz.  If you
define it as  not o Real.==  then (currently) there would be an extra not
instruction.  But, I should be able to peephole that away.  In fact, I
really should look into that because any use of the polymorphic != would
suffer from this as well.  So, it will probably be o.k. to drop
Real_nequal.

> Real.qequal, I bet the definition in mlton-lib.h is wrong, since it is
> equivalent (I believe) to Real_equal.  I don't know if there is a way to get
> what we want in one C operator.  So, my bet as to the right thing to do is to
> drop Real_qequal as a primitive and to define Real.qequal in the basis library
> as
>
> val op ?= = fn (x, y) => isNan x orelse isNan y orelse x == y

Here, there really is an efficiency issue.  As I said at the end of my
last email, I figured out the correct maskings of the status word to do
this as one comparision; currently  isNan  is implemented as an FFI call.
I can probably inline the  isNan  function at some future point in time,
but it would never be as fast as the native assembly.  So, I'd say keep
Real_qequal and do
#define Real_qequal(x,y) ( (isNan(x) || isNan(y)) || ((x) == (y)) )