Real.maxFinite and friends

Matthew Fluet fluet@CS.Cornell.EDU
Fri, 5 Oct 2001 18:10:38 -0400 (EDT)


> > I made Real.maxFinite and friends constants stored in
> > src/runtime/basis/Real_const.S.  Now the
> > src/basis-library/misc/primitive.sml has declarations of the form
> > val maxFinite = _ffi "Real_maxFinite": real;
> 
> Is there any problem with making maxFinite and frieds _prim's?  

Not really; as a first pass, _ffi's are easier to add than _prim's.  The
semantics, though, will need to be the same, there is no load floating
point constant, just move float from one memory location to another.  So,
we still have the Real_const.S file around defining them.

If this is reasonable, then I would like to add to the Prim.Name.t
datatype
	| Real_const of RealConst
where RealConst ranges of maxFinite, and friends; probably add
posInf, negInf, and Math.pi and Math.e as well -- I bet those get caught
in closures more often than the Real.* constants.  

(* All my bad examples where minNormalPos should be minPos.  That's what I
get for doing all the examples last night on another machine and telling
myself, "The examples are so short, how can I get them wrong when I type
them in tomorrow." *)

So, yes I kept meaning minNormalPos to be minPos.

> This doesn't seem strange to me.  r is just some positive *non-normal*
> number.  Dividing minNormalPos by 3 creates a perfectly sensible 64
> bit *non-normal* number.  I think you are confusing minNormalPos and
> minPos.

Yes, you can get r to be some positive (non-zero) number that is smaller
than the (proposed) minimal positive number.

> 1. There is no easy way to get a sensible semantics keeping around
> both 80 bit and 64 bit.
> 

> 2. Using only 64 bit (with -ieee-fp true) is too costly.

Yes; also I don't believe that setting the FPU control word really gets
you 64 bit semantics, although the impression in the IA guide is that it
should.

> 4. In the short run, don't worry about bouncing floats to memory for
> *any* primitives.  I.E., treat isNormal just like we treat +.  I
> realize that this will make the C and native backends different, but
> I'm ok with that.  To make amends with numerical analysists, we keep
> around -ieee-fp true and add a new primitive, MLton.Real.to64, which
> forces 80 to 64.  That way, if someone needs to write a sensitive
> algorithm, they can, without paying the entire cost of -ieee-fp true.

That seems reasonable, although I think that we would also want to make
the basis implementation of Real64 to be equivalent to Real80, except with
every arithmetic op wrapped with MLton.Real.to64 and MLton.Real.from64. 
(We really only have primitives for doing ops at 80bits; there is no need
to have Real64_add in addition to Real80_add.  MLton.Real.from64 would
really just correspond to a floating point load of the right size.) The
constants would need to be generated by hand. The only thing that isn't
clear to me is how to handle floating point constants; are they overloaded
by context the way ints are; 

open Real64
val r1 = 0.123
open Real80
val r2 = 0.123

This will complicate the constants that are generated for the .c stub
file, but not necessarily by that much.