[commit: packages/base] ghc-7.8: Fix regression in Data.Fixed Read instance (re #9231) (99462b6)

git at git.haskell.org git at git.haskell.org
Thu Jun 26 08:33:34 UTC 2014


Repository : ssh://git@git.haskell.org/base

On branch  : ghc-7.8
Link       : http://ghc.haskell.org/trac/ghc/changeset/99462b6877308003442942cbddb3296f29cfb9a8/base

>---------------------------------------------------------------

commit 99462b6877308003442942cbddb3296f29cfb9a8
Author: Herbert Valerio Riedel <hvr at gnu.org>
Date:   Tue Jun 24 11:42:06 2014 +0200

    Fix regression in Data.Fixed Read instance (re #9231)
    
    `convertFixed` operates under the wrong assumption that
    `Data.Fixed.resolution` returns a base-10 exponent `e`, whereas it
    actually returns the power-of-10 value `10^e`.
    
    So while the code (that was introduced in 5f19f951d8 / #7483) happens to
    compute a correct result by coincidence, it allocates huge integer values
    in the process (i.e. `10^(10^e)`) which cause long computations which
    eventually result in out-of-memory conditions for `e`-values beyond
    `Data.Fixed.Milli`.
    
    A proper long-term fix would probably be to extend the `HasResolution`
    type-class to have a 2nd method providing the `e` value.
    
    Signed-off-by: Herbert Valerio Riedel <hvr at gnu.org>
    
    (cherry picked from commit [c1035d51edaac2f388a0630e2ad25391e7e3c1ab/ghc])
    
    Differential Revision: https://phabricator.haskell.org/D25


>---------------------------------------------------------------

99462b6877308003442942cbddb3296f29cfb9a8
 Data/Fixed.hs | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Data/Fixed.hs b/Data/Fixed.hs
index f5fb896..984e1f3 100644
--- a/Data/Fixed.hs
+++ b/Data/Fixed.hs
@@ -158,9 +158,10 @@ instance (HasResolution a) => Read (Fixed a) where
 
 convertFixed :: forall a . HasResolution a => Lexeme -> ReadPrec (Fixed a)
 convertFixed (Number n)
- | Just (i, f) <- numberToFixed r n =
-    return (fromInteger i + (fromInteger f / (10 ^ r)))
-    where r = resolution (undefined :: Fixed a)
+ | Just (i, f) <- numberToFixed e n =
+    return (fromInteger i + (fromInteger f / fromInteger r))
+    where r = resolution (undefined :: Fixed a) -- = 10^e
+          e = round (logBase 10 (fromInteger r) :: Double)
 convertFixed _ = pfail
 
 data E0 = E0



More information about the ghc-commits mailing list