-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Numbers represented using scientific notation -- -- Data.Scientific provides the number type Scientific. -- Scientific numbers are arbitrary precision and space efficient. They -- are represented using scientific notation. The implementation -- uses a coefficient c :: Integer and a base-10 exponent -- e :: Int. A scientific number corresponds to the -- Fractional number: fromInteger c * 10 ^^ -- e. -- -- Note that since we're using an Int to represent the exponent -- these numbers aren't truly arbitrary precision. I intend to change the -- type of the exponent to Integer in a future release. -- -- The main application of Scientific is to be used as the target -- of parsing arbitrary precision numbers coming from an untrusted -- source. The advantages over using Rational for this are that: -- --
-- >>> read "1e1000000000" :: Scientific -- 1.0e1000000000 ---- --
-- > read "1e1000000000" :: Scientific -- 1.0e1000000000 ---- --
-- import qualified Data.Scientific as Scientific --module Data.Scientific -- | An arbitrary-precision number represented using scientific -- notation. -- -- This type describes the set of all Reals which have a -- finite decimal expansion. -- -- A scientific number with coefficient c and -- base10Exponent e corresponds to the Fractional -- number: fromInteger c * 10 ^^ e data Scientific -- | scientific c e constructs a scientific number which -- corresponds to the Fractional number: fromInteger c -- * 10 ^^ e. scientific :: Integer -> Int -> Scientific -- | The coefficient of a scientific number. -- -- Note that this number is not necessarily normalized, i.e. it could -- contain trailing zeros. -- -- Scientific numbers are automatically normalized when pretty printed or -- in toDecimalDigits. -- -- Use normalize to do manual normalization. -- -- WARNING: coefficient and base10exponent violate -- substantivity of Eq. -- --
-- >>> let x = scientific 1 2 -- -- >>> let y = scientific 100 0 -- -- >>> x == y -- True ---- -- but -- --
-- >>> (coefficient x == coefficient y, base10Exponent x == base10Exponent y) -- (False,False) --coefficient :: Scientific -> Integer -- | The base-10 exponent of a scientific number. base10Exponent :: Scientific -> Int -- | Return True if the scientific is a floating point, False -- otherwise. -- -- Also see: floatingOrInteger. isFloating :: Scientific -> Bool -- | Return True if the scientific is an integer, False -- otherwise. -- -- Also see: floatingOrInteger. isInteger :: Scientific -> Bool -- | Although fromRational is unsafe because it will throw errors on -- repeating decimals, unsafeFromRational is even more -- unsafe because it will diverge instead (i.e loop and consume all -- space). Though it will be more efficient because it doesn't need to -- consume space linear in the number of digits in the resulting -- scientific to detect the repetition. -- -- Consider using fromRationalRepetend for these rationals which -- will detect the repetition and indicate where it starts. unsafeFromRational :: Rational -> Scientific -- | Like fromRational and unsafeFromRational, this function -- converts a Rational to a Scientific but instead of -- failing or diverging (i.e loop and consume all space) on repeating -- decimals it detects the repeating part, the repetend, and -- returns where it starts. -- -- To detect the repetition this function consumes space linear in the -- number of digits in the resulting scientific. In order to bound the -- space usage an optional limit can be specified. If the number of -- digits reaches this limit Left (s, r) will be returned. Here -- s is the Scientific constructed so far and r -- is the remaining Rational. toRational s + r yields the -- original Rational -- -- If the limit is not reached or no limit was specified Right (s, -- mbRepetendIx) will be returned. Here s is the -- Scientific without any repetition and mbRepetendIx -- specifies if and where in the fractional part the repetend begins. -- -- For example: -- --
-- fromRationalRepetend Nothing (1 % 28) == Right (3.571428e-2, Just 2) ---- -- This represents the repeating decimal: -- 0.03571428571428571428... which is sometimes also -- unambiguously denoted as 0.03(571428). Here the repetend is -- enclosed in parentheses and starts at the 3rd digit (index 2) in the -- fractional part. Specifying a limit results in the following: -- --
-- fromRationalRepetend (Just 4) (1 % 28) == Left (3.5e-2, 1 % 1400) ---- -- You can expect the following property to hold. -- --
-- forall (mbLimit :: Maybe Int) (r :: Rational). -- r == (case fromRationalRepetend mbLimit r of -- Left (s, r') -> toRational s + r' -- Right (s, mbRepetendIx) -> -- case mbRepetendIx of -- Nothing -> toRational s -- Just repetendIx -> toRationalRepetend s repetendIx) --fromRationalRepetend :: Maybe Int -> Rational -> Either (Scientific, Rational) (Scientific, Maybe Int) -- | Like fromRationalRepetend but always accepts a limit. fromRationalRepetendLimited :: Int -> Rational -> Either (Scientific, Rational) (Scientific, Maybe Int) -- | Like fromRationalRepetend but doesn't accept a limit. fromRationalRepetendUnlimited :: Rational -> (Scientific, Maybe Int) -- | Converts a Scientific with a repetend (a repeating part -- in the fraction), which starts at the given index, into its -- corresponding Rational. -- -- For example to convert the repeating decimal 0.03(571428) you -- would use: toRationalRepetend 0.03571428 2 == 1 % 28 -- -- Preconditions for toRationalRepetend s r: -- --
r >= 0
r < -(base10Exponent s)
-- (fromInteger nonRepetend + repetend % nines) / -- fromInteger (10^^r) -- where -- c = coefficient s -- e = base10Exponent s -- -- -- Size of the fractional part. -- f = (-e) -- -- -- Size of the repetend. -- n = f - r -- -- m = 10^^n -- -- (nonRepetend, repetend) = c `quotRem` m -- -- nines = m - 1 ---- -- Also see: fromRationalRepetend. toRationalRepetend :: Scientific -> Int -> Rational -- | floatingOrInteger determines if the scientific is floating -- point or integer. -- -- In case it's floating-point the scientific is converted to the desired -- RealFloat using toRealFloat and wrapped in Left. -- -- In case it's integer to scientific is converted to the desired -- Integral and wrapped in Right. -- -- WARNING: To convert the scientific to an integral the magnitude -- 10^e needs to be computed. If applied to a huge exponent this -- could take a long time. Even worse, when the destination type is -- unbounded (i.e. Integer) it could fill up all space and crash -- your program! So don't apply this function to untrusted input but use -- toBoundedInteger instead. -- -- Also see: isFloating or isInteger. floatingOrInteger :: (RealFloat r, Integral i) => Scientific -> Either r i -- | Safely convert a Scientific number into a RealFloat -- (like a Double or a Float). -- -- Note that this function uses realToFrac -- (fromRational . toRational) internally but it -- guards against computing huge Integer magnitudes (10^e) that -- could fill up all space and crash your program. If the -- base10Exponent of the given Scientific is too big or too -- small to be represented in the target type, Infinity or 0 will be -- returned respectively. Use toBoundedRealFloat which explicitly -- handles this case by returning Left. -- -- Always prefer toRealFloat over realToFrac when -- converting from scientific numbers coming from an untrusted source. toRealFloat :: RealFloat a => Scientific -> a -- | Preciser version of toRealFloat. If the base10Exponent -- of the given Scientific is too big or too small to be -- represented in the target type, Infinity or 0 will be returned as -- Left. toBoundedRealFloat :: RealFloat a => Scientific -> Either a a -- | Convert a Scientific to a bounded integer. -- -- If the given Scientific doesn't fit in the target -- representation, it will return Nothing. -- -- This function also guards against computing huge Integer magnitudes -- (10^e) that could fill up all space and crash your program. toBoundedInteger :: (Integral i, Bounded i) => Scientific -> Maybe i -- | Convert a RealFloat (like a Double or Float) into -- a Scientific number. -- -- Note that this function uses floatToDigits to compute the -- digits and exponent of the RealFloat number. Be aware that the -- algorithm used in floatToDigits doesn't work as expected for -- some numbers, e.g. as the Double 1e23 is converted to -- 9.9999999999999991611392e22, and that value is shown as -- 9.999999999999999e22 rather than the shorter 1e23; -- the algorithm doesn't take the rounding direction for values exactly -- half-way between two adjacent representable values into account, so if -- you have a value with a short decimal representation exactly half-way -- between two adjacent representable values, like 5^23*2^e for -- e close to 23, the algorithm doesn't know in which direction -- the short decimal representation would be rounded and computes more -- digits fromFloatDigits :: RealFloat a => a -> Scientific -- | A parser for parsing a floating-point number into a Scientific -- value. Example: -- --
-- > import Text.ParserCombinators.ReadP (readP_to_S) -- > readP_to_S scientificP "3" -- [(3.0,"")] -- > readP_to_S scientificP "3.0e2" -- [(3.0,"e2"),(300.0,"")] -- > readP_to_S scientificP "+3.0e+2" -- [(3.0,"e+2"),(300.0,"")] -- > readP_to_S scientificP "-3.0e-2" -- [(-3.0,"e-2"),(-3.0e-2,"")] ---- -- Note: This parser only parses the number itself; it does not parse any -- surrounding parentheses or whitespaces. scientificP :: ReadP Scientific -- | Like show but provides rendering options. formatScientific :: FPFormat -> Maybe Int -> Scientific -> String -- | Control the rendering of floating point numbers. data FPFormat -- | Scientific notation (e.g. 2.3e123). Exponent :: FPFormat -- | Standard decimal notation. Fixed :: FPFormat -- | Use decimal notation for values between 0.1 and -- 9,999,999, and scientific notation otherwise. Generic :: FPFormat -- | Similar to floatToDigits, toDecimalDigits takes a -- positive Scientific number, and returns a list of digits and a -- base-10 exponent. In particular, if x>=0, and -- --
-- toDecimalDigits x = ([d1,d2,...,dn], e) ---- -- then -- --
n >= 1
x = 0.d1d2...dn * (10^^e)
0 <= di <= 9
null $ takeWhile (==0) $ reverse [d1,d2,...,dn]