diff options
author | Herbert Valerio Riedel <hvr@gnu.org> | 2014-06-24 11:42:06 +0200 |
---|---|---|
committer | Herbert Valerio Riedel <hvr@gnu.org> | 2014-06-24 12:27:16 +0200 |
commit | c1035d51edaac2f388a0630e2ad25391e7e3c1ab (patch) | |
tree | 76d69bebfe606a6321b1209b331087712b5c8461 /libraries | |
parent | 7a783746972561565eacea634512c3888ded6ec2 (diff) | |
download | haskell-c1035d51edaac2f388a0630e2ad25391e7e3c1ab.tar.gz |
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@gnu.org>
Differential Revision: https://phabricator.haskell.org/D25
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/base/Data/Fixed.hs | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/libraries/base/Data/Fixed.hs b/libraries/base/Data/Fixed.hs index b946d5edde..b3af208469 100644 --- a/libraries/base/Data/Fixed.hs +++ b/libraries/base/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 |