on master help sign in
Convert to Rational before converting to Double
6d91b78Harendra Kumar
core/src/Streamly/Internal/Unicode/Parser.hs+24−8
@@ -51,6 +51,9 @@ module Streamly.Internal.Unicode.Parser
51 , double
51 , double
52 , decimal
52 , decimal
53 , hexadecimal
53 , hexadecimal
54+
55+ -- * Utilities
56+ , mkDouble
54 )
57 )
55where
58where
56
59
@@ -404,6 +407,19 @@ number = Parser (\s a -> return $ step s a) initial (return . extract)
404 extract (SPAfterExponent mult num decimalPlaces powerMult powerNum) =
407 extract (SPAfterExponent mult num decimalPlaces powerMult powerNum) =
405 Done 0 $ exitSPAfterExponent mult num decimalPlaces powerMult powerNum
408 Done 0 $ exitSPAfterExponent mult num decimalPlaces powerMult powerNum
406
409
410+-- XXX We can have a `realFloat` parser instead to parse any RealFloat value.
411+-- And a integral parser to read any integral value.
412+
413+-- | @mkDouble mantissa exponent@ converts a mantissa and exponent to a
414+-- 'Double' value equivalent to @mantissa * 10^exponent@. It does not check for
415+-- overflow, powers more than 308 will overflow.
416+{-# INLINE mkDouble #-}
417+mkDouble :: Integer -> Int -> Double
418+mkDouble mantissa power =
419+ if power > 0
420+ then fromRational (fromIntegral (mantissa * 10 ^ power))
421+ else fromRational (mantissa % 10 ^ (-power))
422+
407-- | Parse a decimal 'Double' value. This parser accepts an optional sign (+ or
423-- | Parse a decimal 'Double' value. This parser accepts an optional sign (+ or
408-- -) followed by at least one decimal digit. Decimal digits are optionally
424-- -) followed by at least one decimal digit. Decimal digits are optionally
409-- followed by a decimal point and at least one decimal digit after the point.
425-- followed by a decimal point and at least one decimal digit after the point.
@@ -414,6 +430,13 @@ number = Parser (\s a -> return $ step s a) initial (return . extract)
414--
430--
415-- >>> import qualified Streamly.Data.Stream as Stream
431-- >>> import qualified Streamly.Data.Stream as Stream
416-- >>> import qualified Streamly.Unicode.Parser as Unicode
432-- >>> import qualified Streamly.Unicode.Parser as Unicode
433+-- >>> import qualified Streamly.Internal.Unicode.Parser as Unicode (number, mkDouble)
434+--
435+-- Definition:
436+--
437+-- >>> double = uncurry Unicode.mkDouble <$> Unicode.number
438+--
439+-- Examples:
417--
440--
418-- >>> p = Stream.parse Unicode.double . Stream.fromList
441-- >>> p = Stream.parse Unicode.double . Stream.fromList
419--
442--
@@ -450,11 +473,4 @@ number = Parser (\s a -> return $ step s a) initial (return . extract)
450--
473--
451{-# INLINE double #-}
474{-# INLINE double #-}
452double :: Monad m => Parser Char m Double
475double :: Monad m => Parser Char m Double
453−double = fmap f number
476+double = uncurry mkDouble <$> number
454−
455− where
456−
457− f (m, e) =
458− if e > 0
459− then fromIntegral (m * 10 ^ e)
460− else fromRational (m % 10 ^ (-e))