Floating point and RealFrac
Daniel Fischer
daniel.is.fischer at googlemail.com
Sun May 15 23:41:47 CEST 2011
Looking at the old bug list again, there are a couple of tickets I might be
able to do something about. Since library submissions are somewhat painful,
though, and I'm not bitten by the issues, I'd like to know if there's
general interest to do something about them.
1)
http://hackage.haskell.org/trac/ghc/ticket/2269
Feature request: add primops word2Double#, double2Word#, word2Float#,
float2Word#
Well, I don't know how to create primops, but I could twiddle a few bits in
C to produce a hopefully faster conversion than we have now.
2)
http://hackage.haskell.org/trac/ghc/ticket/2281
a fast 'fraction' function for Double
Although
fraction x = snd (properFraction x :: (Integer, TYPE_OF_x))
, when compiled with optimisations, is not as slow as it used to be, it's
still not very fast. A binding to modf/modff or some bit-twiddling in C
should be faster. If there's demand for this, should a `fraction' function
be added to RealFrac, should standalone functions fractionFloat and
fractionDouble be added to GHC.Float with rewrite rules
snd (properFraction x) -> fractionTYPE x
?
3)
http://hackage.haskell.org/trac/ghc/ticket/3676
realToFrac misbehaves on NaNs, -0.0 and infinities (for Float -> Double)
when the rewrite rule doesn't fire.
As long as the realToFrac conversion [without rewrite rules] goes through
Rational, this is basically unfixable.
So a real fix would necessitate a language change.
Some ideas have been shortly discussed in
http://www.haskell.org/pipermail/haskell-prime/2010-February/003139.html
and replies.
The most reasonable candidates IMO are
- a dedicated floating point conversion, with
* a type alias FloatMax for the largest (real + infinities + NaNs)
Floating point type, currently Double
* methods toFloatMax and fromFloatMax added to RealFloat
* the conversion function
floatConvert :: (RealFloat a, RealFloat b) => a -> b
- adding a type specifically for conversions between different number types
that caters for special values, something along the lines of
data NumRep
= NegativeZero
| Infinity Bool -- to indicate sign
| NaN -- possibly with a parameter to encode different NaNs
| BinExp Integer Int -- m*2^e
| Rat Rational
| Entire Integer -- ?
and let realToFrac convert via this type.
The BinExp constructor would allow a more efficient conversion between
base-2 floating point types than fromRational . toRational can be.
If such a type would also be used for the Read instances, instead of
Rational, adding a constructor for base-10 representations would be useful
(cf. http://hackage.haskell.org/trac/ghc/ticket/3897 ) [and Rational could
be freed from the invalid values 0:%0, ±1:%0].
Both candidates would be major undertakings and have their downsides.
I can live with the current state of affairs, what bugs me most about it is
the open ticket.
More information about the Libraries
mailing list