
On Friday 26 August 2011, 22:29:20, Ian Lynagh wrote:
On Fri, Aug 26, 2011 at 10:08:25PM +0200, Daniel Fischer wrote:
a nontrivial performance penalty.
It would be nice if the current function, without performance penalty, were ultimately renamed to unsafeDecodeFloat.
Yes, however, removing decodeFloat or changing its type would break existing code. I have no idea how much, so I'm not sure whether renaming the current function and giving decodeFloat a new type is feasible. I suspect it's not. So then we'd have unsafeDecodeFloat -- current safeDecodeFloat -- new, safe decodeFloat -- what to do with that? And what would we do with significand/exponent on NaN/Infinity? error?
A new function could return something like data DecodedFloat = Decoded Integer Int
| NaN | Infinity | NegativeInfinity | NegativeZero
(I'm not sure which constructors you'd want exactly).
Something like that. I'm pondering something more general, though. data RealRep = I Integer | R Rational | Bin Integer Int -- m*2^e | Dec Integer Int -- m*10^e | NaN ? -- not sure how to treat different NaNs | Infinity | NegativeInfinity | NegativeZero -- possibly more to represent all (usual) types of Real numbers. Using that as intermediate type instead of Rational in realToFrac would allow a correct Double <-> Float (and newtypes) conversion also without rewrite rules (and should be faster than 'fromRational . toRational' for these, since it would be basically 'uncurry encodeFloat . decodeFloat'). Using that instead of Rational in reading would allow curing http://hackage.haskell.org/trac/ghc/ticket/3897 (although that probably isn't a real life problem; and it could well be slower for the average input string). And we could get rid of infinity = 1 :% 0 notANumber = 0 :% 0. But it would be a *huge* change.