{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE DeriveLift #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE ViewPatterns #-}
module Data.Scientific
( Scientific
, scientific
, coefficient
, base10Exponent
, isFloating
, isInteger
, unsafeFromRational
, fromRationalRepetend
, fromRationalRepetendLimited
, fromRationalRepetendUnlimited
, toRationalRepetend
, floatingOrInteger
, toRealFloat
, toBoundedRealFloat
, toBoundedInteger
, fromFloatDigits
, scientificP
, formatScientific
, FPFormat(..)
, toDecimalDigits
, normalize
) where
import Control.Exception (throw, ArithException(DivideByZero))
import Control.Monad (mplus)
import Control.DeepSeq (NFData, rnf)
import Data.Binary (Binary, get, put)
import Data.Char (intToDigit, ord)
import Data.Data (Data)
import Data.Hashable (Hashable(..))
import Data.Int (Int8, Int16, Int32, Int64)
import qualified Data.Map as M (Map, empty, insert, lookup)
import Data.Maybe (isJust)
import Data.Ratio ((%), numerator, denominator)
import Data.Typeable (Typeable)
import Data.Word (Word8, Word16, Word32, Word64)
import Math.NumberTheory.Logarithms (integerLog10')
import qualified Numeric (floatToDigits)
import qualified Text.Read as Read
import Text.Read (readPrec)
import qualified Text.ParserCombinators.ReadPrec as ReadPrec
import qualified Text.ParserCombinators.ReadP as ReadP
import Text.ParserCombinators.ReadP ( ReadP )
import Data.Text.Lazy.Builder.RealFloat (FPFormat(..))
import GHC.Integer.Compat (quotRemInteger, quotInteger, divInteger)
import Utils (maxExpt, roundTo, magnitude)
import Language.Haskell.TH.Syntax (Lift (..))
data Scientific = Scientific
{ Scientific -> Integer
coefficient :: !Integer
, Scientific -> Int
base10Exponent :: {-# UNPACK #-} !Int
} deriving (Typeable, Typeable Scientific
Typeable Scientific =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Scientific -> c Scientific)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Scientific)
-> (Scientific -> Constr)
-> (Scientific -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Scientific))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c Scientific))
-> ((forall b. Data b => b -> b) -> Scientific -> Scientific)
-> (forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Scientific -> r)
-> (forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Scientific -> r)
-> (forall u. (forall d. Data d => d -> u) -> Scientific -> [u])
-> (forall u.
Int -> (forall d. Data d => d -> u) -> Scientific -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Scientific -> m Scientific)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Scientific -> m Scientific)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Scientific -> m Scientific)
-> Data Scientific
Scientific -> Constr
Scientific -> DataType
(forall b. Data b => b -> b) -> Scientific -> Scientific
forall a.
Typeable a =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Scientific -> u
forall u. (forall d. Data d => d -> u) -> Scientific -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Scientific -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Scientific -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Scientific -> m Scientific
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Scientific -> m Scientific
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Scientific
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Scientific -> c Scientific
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Scientific)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Scientific)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Scientific -> c Scientific
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Scientific -> c Scientific
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Scientific
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Scientific
$ctoConstr :: Scientific -> Constr
toConstr :: Scientific -> Constr
$cdataTypeOf :: Scientific -> DataType
dataTypeOf :: Scientific -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Scientific)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Scientific)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Scientific)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Scientific)
$cgmapT :: (forall b. Data b => b -> b) -> Scientific -> Scientific
gmapT :: (forall b. Data b => b -> b) -> Scientific -> Scientific
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Scientific -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Scientific -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Scientific -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Scientific -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Scientific -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Scientific -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Scientific -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Scientific -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Scientific -> m Scientific
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Scientific -> m Scientific
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Scientific -> m Scientific
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Scientific -> m Scientific
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Scientific -> m Scientific
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Scientific -> m Scientific
Data)
scientific :: Integer -> Int -> Scientific
scientific :: Integer -> Int -> Scientific
scientific = Integer -> Int -> Scientific
Scientific
deriving instance Lift Scientific
instance NFData Scientific where
rnf :: Scientific -> ()
rnf (Scientific Integer
_ Int
_) = ()
instance Hashable Scientific where
hashWithSalt :: Int -> Scientific -> Int
hashWithSalt Int
salt Scientific
s = Int
salt Int -> Integer -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Integer
c Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
e
where
Scientific Integer
c Int
e = Scientific -> Scientific
normalize Scientific
s
instance Binary Scientific where
put :: Scientific -> Put
put (Scientific Integer
c Int
e) = Integer -> Put
forall t. Binary t => t -> Put
put Integer
c Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Integer -> Put
forall t. Binary t => t -> Put
put (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
e)
get :: Get Scientific
get = Integer -> Int -> Scientific
Scientific (Integer -> Int -> Scientific)
-> Get Integer -> Get (Int -> Scientific)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Integer
forall t. Binary t => Get t
get Get (Int -> Scientific) -> Get Int -> Get Scientific
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> Get Integer -> Get Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Integer
forall t. Binary t => Get t
get)
instance Eq Scientific where
Scientific Integer
c1 Int
e1 == :: Scientific -> Scientific -> Bool
== Scientific Integer
c2 Int
e2
| Int
e1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
e2 = Integer
c1 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
c2
| Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
rem Integer
c1 Integer
10 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0
, Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
rem Integer
c2 Integer
10 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0
= Int
e1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
e2 Bool -> Bool -> Bool
&& Integer
c1 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
c2
Scientific Integer
c1 Int
e1 == Scientific Integer
c2 Int
e2 = case Integer -> Integer -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Integer
c1 Integer
0 of
Ordering
EQ -> Integer
c2 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0
Ordering
LT -> if Integer
c2 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 then Integer -> Int -> Integer -> Int -> Bool
eqScientific1 (-Integer
c1) Int
e1 (-Integer
c2) Int
e2 else Bool
False
Ordering
GT -> if Integer
c2 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 then Integer -> Int -> Integer -> Int -> Bool
eqScientific1 Integer
c1 Int
e1 Integer
c2 Int
e2 else Bool
False
eqScientific1 :: Integer -> Int -> Integer -> Int -> Bool
eqScientific1 :: Integer -> Int -> Integer -> Int -> Bool
eqScientific1 Integer
c1 Int
e1 Integer
c2 Int
e2
| Integer
log1 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
log2 = Bool
False
| Bool
otherwise = case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
e1 Int
e2 of
Ordering
EQ -> Integer
c1 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
c2
Ordering
GT -> Integer
c1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Num a => Int -> a
magnitude (Int
e1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
e2) Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
c2
Ordering
LT -> Integer
c1 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
c2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Num a => Int -> a
magnitude (Int
e2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
e1)
where
log1 :: Integer
log1 = Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Integer -> Int
integerLog10' Integer
c1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
e1
log2 :: Integer
log2 = Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Integer -> Int
integerLog10' Integer
c2) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
e2
instance Ord Scientific where
compare :: Scientific -> Scientific -> Ordering
compare (Scientific Integer
c1 Int
e1) (Scientific Integer
c2 Int
e2)
| Int
e1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
e2 = Integer -> Integer -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Integer
c1 Integer
c2
compare (Scientific Integer
c1 Int
e1) (Scientific Integer
c2 Int
e2) = case Integer -> Integer -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Integer
c1 Integer
0 of
Ordering
EQ -> Integer -> Integer -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Integer
0 Integer
c2
Ordering
LT -> if Integer
c2 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 then Integer -> Int -> Integer -> Int -> Ordering
cmpScientific (-Integer
c2) Int
e2 (-Integer
c1) Int
e1 else Ordering
LT
Ordering
GT -> if Integer
c2 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 then Integer -> Int -> Integer -> Int -> Ordering
cmpScientific Integer
c1 Int
e1 Integer
c2 Int
e2 else Ordering
GT
cmpScientific :: Integer -> Int -> Integer -> Int -> Ordering
cmpScientific :: Integer -> Int -> Integer -> Int -> Ordering
cmpScientific Integer
c1 Int
e1 Integer
c2 Int
e2 = case Integer -> Integer -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Integer
log1 Integer
log2 of
Ordering
GT -> Ordering
GT
Ordering
LT -> Ordering
LT
Ordering
EQ -> case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
e1 Int
e2 of
Ordering
EQ -> Integer -> Integer -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Integer
c1 Integer
c2
Ordering
GT -> Integer -> Integer -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Integer
c1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Num a => Int -> a
magnitude (Int
e1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
e2)) Integer
c2
Ordering
LT -> Integer -> Integer -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Integer
c1 (Integer
c2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Num a => Int -> a
magnitude (Int
e2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
e1))
where
log1 :: Integer
log1 = Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Integer -> Int
integerLog10' Integer
c1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
e1
log2 :: Integer
log2 = Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Integer -> Int
integerLog10' Integer
c2) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
e2
instance Num Scientific where
Scientific Integer
c1 Int
e1 + :: Scientific -> Scientific -> Scientific
+ Scientific Integer
c2 Int
e2
| Int
e1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
e2 = Integer -> Int -> Scientific
Scientific (Integer
c1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
c2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
l) Int
e1
| Bool
otherwise = Integer -> Int -> Scientific
Scientific (Integer
c1Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
r Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
c2 ) Int
e2
where
l :: Integer
l = Int -> Integer
forall a. Num a => Int -> a
magnitude (Int
e2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
e1)
r :: Integer
r = Int -> Integer
forall a. Num a => Int -> a
magnitude (Int
e1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
e2)
{-# INLINABLE (+) #-}
Scientific Integer
c1 Int
e1 - :: Scientific -> Scientific -> Scientific
- Scientific Integer
c2 Int
e2
| Int
e1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
e2 = Integer -> Int -> Scientific
Scientific (Integer
c1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
c2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
l) Int
e1
| Bool
otherwise = Integer -> Int -> Scientific
Scientific (Integer
c1Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
r Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
c2 ) Int
e2
where
l :: Integer
l = Int -> Integer
forall a. Num a => Int -> a
magnitude (Int
e2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
e1)
r :: Integer
r = Int -> Integer
forall a. Num a => Int -> a
magnitude (Int
e1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
e2)
{-# INLINABLE (-) #-}
Scientific Integer
c1 Int
e1 * :: Scientific -> Scientific -> Scientific
* Scientific Integer
c2 Int
e2 =
Integer -> Int -> Scientific
Scientific (Integer
c1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
c2) (Int
e1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
e2)
{-# INLINABLE (*) #-}
abs :: Scientific -> Scientific
abs (Scientific Integer
c Int
e) = Integer -> Int -> Scientific
Scientific (Integer -> Integer
forall a. Num a => a -> a
abs Integer
c) Int
e
{-# INLINABLE abs #-}
negate :: Scientific -> Scientific
negate (Scientific Integer
c Int
e) = Integer -> Int -> Scientific
Scientific (Integer -> Integer
forall a. Num a => a -> a
negate Integer
c) Int
e
{-# INLINABLE negate #-}
signum :: Scientific -> Scientific
signum (Scientific Integer
c Int
_) = Integer -> Int -> Scientific
Scientific (Integer -> Integer
forall a. Num a => a -> a
signum Integer
c) Int
0
{-# INLINABLE signum #-}
fromInteger :: Integer -> Scientific
fromInteger Integer
i = Integer -> Int -> Scientific
Scientific Integer
i Int
0
{-# INLINABLE fromInteger #-}
instance Real Scientific where
toRational :: Scientific -> Rational
toRational (Scientific Integer
c Int
e)
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Integer
c Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Int -> Integer
forall a. Num a => Int -> a
magnitude (-Int
e)
| Bool
otherwise = (Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Num a => Int -> a
magnitude Int
e) Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
1
{-# INLINABLE toRational #-}
{-# RULES
"realToFrac_toRealFloat_Double"
realToFrac = toRealFloat :: Scientific -> Double #-}
{-# RULES
"realToFrac_toRealFloat_Float"
realToFrac = toRealFloat :: Scientific -> Float #-}
instance Fractional Scientific where
recip :: Scientific -> Scientific
recip = Rational -> Scientific
forall a. Fractional a => Rational -> a
fromRational (Rational -> Scientific)
-> (Scientific -> Rational) -> Scientific -> Scientific
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Rational
forall a. Fractional a => a -> a
recip (Rational -> Rational)
-> (Scientific -> Rational) -> Scientific -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> Rational
forall a. Real a => a -> Rational
toRational
Scientific Integer
c1 Int
e1 / :: Scientific -> Scientific -> Scientific
/ Scientific Integer
c2 Int
e2
| Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Rational -> Scientific
forall a. Fractional a => Rational -> a
fromRational (Rational
x Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ (Integer -> Rational
forall a. Num a => Integer -> a
fromInteger (Int -> Integer
forall a. Num a => Int -> a
magnitude (-Int
d))))
| Bool
otherwise = Rational -> Scientific
forall a. Fractional a => Rational -> a
fromRational (Rational
x Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Integer -> Rational
forall a. Num a => Integer -> a
fromInteger (Int -> Integer
forall a. Num a => Int -> a
magnitude Int
d))
where
d :: Int
d = Int
e1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
e2
x :: Rational
x = Integer
c1 Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
c2
fromRational :: Rational -> Scientific
fromRational Rational
rational =
case Maybe Int
mbRepetendIx of
Maybe Int
Nothing -> Scientific
s
Just Int
_ix -> [Char] -> Scientific
forall a. HasCallStack => [Char] -> a
error ([Char] -> Scientific) -> [Char] -> Scientific
forall a b. (a -> b) -> a -> b
$
[Char]
"fromRational has been applied to a repeating decimal " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
[Char]
"which can't be represented as a Scientific! " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
[Char]
"It's better to avoid performing fractional operations on Scientifics " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
[Char]
"and convert them to other fractional types like Double as early as possible."
where
(Scientific
s, Maybe Int
mbRepetendIx) = Rational -> (Scientific, Maybe Int)
fromRationalRepetendUnlimited Rational
rational
unsafeFromRational :: Rational -> Scientific
unsafeFromRational :: Rational -> Scientific
unsafeFromRational Rational
rational
| Integer
d Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = ArithException -> Scientific
forall a e. Exception e => e -> a
throw ArithException
DivideByZero
| Bool
otherwise = (Integer -> Scientific) -> Integer -> Scientific
forall a b. (Ord a, Num a, Num b) => (a -> b) -> a -> b
positivize (Integer -> Int -> Integer -> Scientific
longDiv Integer
0 Int
0) (Rational -> Integer
forall a. Ratio a -> a
numerator Rational
rational)
where
longDiv :: Integer -> Int -> (Integer -> Scientific)
longDiv :: Integer -> Int -> Integer -> Scientific
longDiv !Integer
c !Int
e Integer
0 = Integer -> Int -> Scientific
Scientific Integer
c Int
e
longDiv !Integer
c !Int
e !Integer
n
| Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
d = Integer -> Int -> Integer -> Scientific
longDiv (Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10) (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10)
| Bool
otherwise = case Integer
n Integer -> Integer -> (# Integer, Integer #)
`quotRemInteger` Integer
d of
(#Integer
q, Integer
r#) -> Integer -> Int -> Integer -> Scientific
longDiv (Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
q) Int
e Integer
r
d :: Integer
d = Rational -> Integer
forall a. Ratio a -> a
denominator Rational
rational
fromRationalRepetend
:: Maybe Int
-> Rational
-> Either (Scientific, Rational)
(Scientific, Maybe Int)
fromRationalRepetend :: Maybe Int
-> Rational
-> Either (Scientific, Rational) (Scientific, Maybe Int)
fromRationalRepetend Maybe Int
mbLimit Rational
rational =
case Maybe Int
mbLimit of
Maybe Int
Nothing -> (Scientific, Maybe Int)
-> Either (Scientific, Rational) (Scientific, Maybe Int)
forall a b. b -> Either a b
Right ((Scientific, Maybe Int)
-> Either (Scientific, Rational) (Scientific, Maybe Int))
-> (Scientific, Maybe Int)
-> Either (Scientific, Rational) (Scientific, Maybe Int)
forall a b. (a -> b) -> a -> b
$ Rational -> (Scientific, Maybe Int)
fromRationalRepetendUnlimited Rational
rational
Just Int
l -> Int
-> Rational
-> Either (Scientific, Rational) (Scientific, Maybe Int)
fromRationalRepetendLimited Int
l Rational
rational
fromRationalRepetendLimited
:: Int
-> Rational
-> Either (Scientific, Rational)
(Scientific, Maybe Int)
fromRationalRepetendLimited :: Int
-> Rational
-> Either (Scientific, Rational) (Scientific, Maybe Int)
fromRationalRepetendLimited Int
l Rational
rational
| Integer
d Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = ArithException
-> Either (Scientific, Rational) (Scientific, Maybe Int)
forall a e. Exception e => e -> a
throw ArithException
DivideByZero
| Integer
num Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = case Integer -> Either (Scientific, Rational) (Scientific, Maybe Int)
longDiv (-Integer
num) of
Left (Scientific
s, Rational
r) -> (Scientific, Rational)
-> Either (Scientific, Rational) (Scientific, Maybe Int)
forall a b. a -> Either a b
Left (-Scientific
s, -Rational
r)
Right (Scientific
s, Maybe Int
mb) -> (Scientific, Maybe Int)
-> Either (Scientific, Rational) (Scientific, Maybe Int)
forall a b. b -> Either a b
Right (-Scientific
s, Maybe Int
mb)
| Bool
otherwise = Integer -> Either (Scientific, Rational) (Scientific, Maybe Int)
longDiv Integer
num
where
num :: Integer
num = Rational -> Integer
forall a. Ratio a -> a
numerator Rational
rational
longDiv :: Integer -> Either (Scientific, Rational) (Scientific, Maybe Int)
longDiv :: Integer -> Either (Scientific, Rational) (Scientific, Maybe Int)
longDiv = Integer
-> Int
-> Map Integer Int
-> Integer
-> Either (Scientific, Rational) (Scientific, Maybe Int)
longDivWithLimit Integer
0 Int
0 Map Integer Int
forall k a. Map k a
M.empty
longDivWithLimit
:: Integer
-> Int
-> M.Map Integer Int
-> (Integer -> Either (Scientific, Rational)
(Scientific, Maybe Int))
longDivWithLimit :: Integer
-> Int
-> Map Integer Int
-> Integer
-> Either (Scientific, Rational) (Scientific, Maybe Int)
longDivWithLimit !Integer
c !Int
e Map Integer Int
_ns Integer
0 = (Scientific, Maybe Int)
-> Either (Scientific, Rational) (Scientific, Maybe Int)
forall a b. b -> Either a b
Right (Integer -> Int -> Scientific
Scientific Integer
c Int
e, Maybe Int
forall a. Maybe a
Nothing)
longDivWithLimit !Integer
c !Int
e Map Integer Int
ns !Integer
n
| Just Int
e' <- Integer -> Map Integer Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Integer
n Map Integer Int
ns = (Scientific, Maybe Int)
-> Either (Scientific, Rational) (Scientific, Maybe Int)
forall a b. b -> Either a b
Right (Integer -> Int -> Scientific
Scientific Integer
c Int
e, Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
e'))
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= (-Int
l) = (Scientific, Rational)
-> Either (Scientific, Rational) (Scientific, Maybe Int)
forall a b. a -> Either a b
Left (Integer -> Int -> Scientific
Scientific Integer
c Int
e, Integer
n Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% (Integer
d Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Num a => Int -> a
magnitude (-Int
e)))
| Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
d = let !ns' :: Map Integer Int
ns' = Integer -> Int -> Map Integer Int -> Map Integer Int
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Integer
n Int
e Map Integer Int
ns
in Integer
-> Int
-> Map Integer Int
-> Integer
-> Either (Scientific, Rational) (Scientific, Maybe Int)
longDivWithLimit (Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10) (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Map Integer Int
ns' (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10)
| Bool
otherwise = case Integer
n Integer -> Integer -> (# Integer, Integer #)
`quotRemInteger` Integer
d of
(#Integer
q, Integer
r#) -> Integer
-> Int
-> Map Integer Int
-> Integer
-> Either (Scientific, Rational) (Scientific, Maybe Int)
longDivWithLimit (Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
q) Int
e Map Integer Int
ns Integer
r
d :: Integer
d = Rational -> Integer
forall a. Ratio a -> a
denominator Rational
rational
fromRationalRepetendUnlimited :: Rational -> (Scientific, Maybe Int)
fromRationalRepetendUnlimited :: Rational -> (Scientific, Maybe Int)
fromRationalRepetendUnlimited Rational
rational
| Integer
d Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = ArithException -> (Scientific, Maybe Int)
forall a e. Exception e => e -> a
throw ArithException
DivideByZero
| Integer
num Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = case Integer -> (Scientific, Maybe Int)
longDiv (-Integer
num) of
(Scientific
s, Maybe Int
mb) -> (-Scientific
s, Maybe Int
mb)
| Bool
otherwise = Integer -> (Scientific, Maybe Int)
longDiv Integer
num
where
num :: Integer
num = Rational -> Integer
forall a. Ratio a -> a
numerator Rational
rational
longDiv :: Integer -> (Scientific, Maybe Int)
longDiv :: Integer -> (Scientific, Maybe Int)
longDiv = Integer
-> Int -> Map Integer Int -> Integer -> (Scientific, Maybe Int)
longDivNoLimit Integer
0 Int
0 Map Integer Int
forall k a. Map k a
M.empty
longDivNoLimit :: Integer
-> Int
-> M.Map Integer Int
-> (Integer -> (Scientific, Maybe Int))
longDivNoLimit :: Integer
-> Int -> Map Integer Int -> Integer -> (Scientific, Maybe Int)
longDivNoLimit !Integer
c !Int
e Map Integer Int
_ns Integer
0 = (Integer -> Int -> Scientific
Scientific Integer
c Int
e, Maybe Int
forall a. Maybe a
Nothing)
longDivNoLimit !Integer
c !Int
e Map Integer Int
ns !Integer
n
| Just Int
e' <- Integer -> Map Integer Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Integer
n Map Integer Int
ns = (Integer -> Int -> Scientific
Scientific Integer
c Int
e, Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
e'))
| Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
d = let !ns' :: Map Integer Int
ns' = Integer -> Int -> Map Integer Int -> Map Integer Int
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Integer
n Int
e Map Integer Int
ns
in Integer
-> Int -> Map Integer Int -> Integer -> (Scientific, Maybe Int)
longDivNoLimit (Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10) (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Map Integer Int
ns' (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10)
| Bool
otherwise = case Integer
n Integer -> Integer -> (# Integer, Integer #)
`quotRemInteger` Integer
d of
(#Integer
q, Integer
r#) -> Integer
-> Int -> Map Integer Int -> Integer -> (Scientific, Maybe Int)
longDivNoLimit (Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
q) Int
e Map Integer Int
ns Integer
r
d :: Integer
d = Rational -> Integer
forall a. Ratio a -> a
denominator Rational
rational
toRationalRepetend
:: Scientific
-> Int
-> Rational
toRationalRepetend :: Scientific -> Int -> Rational
toRationalRepetend Scientific
s Int
r
| Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = [Char] -> Rational
forall a. HasCallStack => [Char] -> a
error [Char]
"toRationalRepetend: Negative repetend index!"
| Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
f = [Char] -> Rational
forall a. HasCallStack => [Char] -> a
error [Char]
"toRationalRepetend: Repetend index >= than number of digits in the fractional part!"
| Bool
otherwise = (Integer -> Rational
forall a. Num a => Integer -> a
fromInteger Integer
nonRepetend Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+ Integer
repetend Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
nines) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/
Integer -> Rational
forall a. Num a => Integer -> a
fromInteger (Int -> Integer
forall a. Num a => Int -> a
magnitude Int
r)
where
c :: Integer
c = Scientific -> Integer
coefficient Scientific
s
e :: Int
e = Scientific -> Int
base10Exponent Scientific
s
f :: Int
f = (-Int
e)
n :: Int
n = Int
f Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
r
m :: Integer
m = Int -> Integer
forall a. Num a => Int -> a
magnitude Int
n
(#Integer
nonRepetend, Integer
repetend#) = Integer
c Integer -> Integer -> (# Integer, Integer #)
`quotRemInteger` Integer
m
nines :: Integer
nines = Integer
m Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1
instance RealFrac Scientific where
properFraction :: forall b. Integral b => Scientific -> (b, Scientific)
properFraction s :: Scientific
s@(Scientific Integer
c Int
e)
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = if Integer -> Int -> Bool
dangerouslySmall Integer
c Int
e
then (b
0, Scientific
s)
else case Integer
c Integer -> Integer -> (# Integer, Integer #)
`quotRemInteger` Int -> Integer
forall a. Num a => Int -> a
magnitude (-Int
e) of
(#Integer
q, Integer
r#) -> (Integer -> b
forall a. Num a => Integer -> a
fromInteger Integer
q, Integer -> Int -> Scientific
Scientific Integer
r Int
e)
| Bool
otherwise = (Scientific -> b
forall a. Num a => Scientific -> a
toIntegral Scientific
s, Scientific
0)
{-# INLINABLE properFraction #-}
truncate :: forall b. Integral b => Scientific -> b
truncate = (Integer -> Int -> b) -> Scientific -> b
forall a. Num a => (Integer -> Int -> a) -> Scientific -> a
whenFloating ((Integer -> Int -> b) -> Scientific -> b)
-> (Integer -> Int -> b) -> Scientific -> b
forall a b. (a -> b) -> a -> b
$ \Integer
c Int
e ->
if Integer -> Int -> Bool
dangerouslySmall Integer
c Int
e
then b
0
else Integer -> b
forall a. Num a => Integer -> a
fromInteger (Integer -> b) -> Integer -> b
forall a b. (a -> b) -> a -> b
$ Integer
c Integer -> Integer -> Integer
`quotInteger` Int -> Integer
forall a. Num a => Int -> a
magnitude (-Int
e)
{-# INLINABLE truncate #-}
round :: forall b. Integral b => Scientific -> b
round = (Integer -> Int -> b) -> Scientific -> b
forall a. Num a => (Integer -> Int -> a) -> Scientific -> a
whenFloating ((Integer -> Int -> b) -> Scientific -> b)
-> (Integer -> Int -> b) -> Scientific -> b
forall a b. (a -> b) -> a -> b
$ \Integer
c Int
e ->
if Integer -> Int -> Bool
dangerouslySmall Integer
c Int
e
then b
0
else let (#Integer
q, Integer
r#) = Integer
c Integer -> Integer -> (# Integer, Integer #)
`quotRemInteger` Int -> Integer
forall a. Num a => Int -> a
magnitude (-Int
e)
n :: b
n = Integer -> b
forall a. Num a => Integer -> a
fromInteger Integer
q
m :: b
m | Integer
r Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = b
n b -> b -> b
forall a. Num a => a -> a -> a
- b
1
| Bool
otherwise = b
n b -> b -> b
forall a. Num a => a -> a -> a
+ b
1
f :: Scientific
f = Integer -> Int -> Scientific
Scientific Integer
r Int
e
in case Integer -> Integer
forall a. Num a => a -> a
signum (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Scientific -> Integer
coefficient (Scientific -> Integer) -> Scientific -> Integer
forall a b. (a -> b) -> a -> b
$ Scientific -> Scientific
forall a. Num a => a -> a
abs Scientific
f Scientific -> Scientific -> Scientific
forall a. Num a => a -> a -> a
- Scientific
0.5 of
-1 -> b
n
Integer
0 -> if b -> Bool
forall a. Integral a => a -> Bool
even b
n then b
n else b
m
Integer
1 -> b
m
Integer
_ -> [Char] -> b
forall a. HasCallStack => [Char] -> a
error [Char]
"round default defn: Bad value"
{-# INLINABLE round #-}
ceiling :: forall b. Integral b => Scientific -> b
ceiling = (Integer -> Int -> b) -> Scientific -> b
forall a. Num a => (Integer -> Int -> a) -> Scientific -> a
whenFloating ((Integer -> Int -> b) -> Scientific -> b)
-> (Integer -> Int -> b) -> Scientific -> b
forall a b. (a -> b) -> a -> b
$ \Integer
c Int
e ->
if Integer -> Int -> Bool
dangerouslySmall Integer
c Int
e
then if Integer
c Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
0
then b
0
else b
1
else case Integer
c Integer -> Integer -> (# Integer, Integer #)
`quotRemInteger` Int -> Integer
forall a. Num a => Int -> a
magnitude (-Int
e) of
(#Integer
q, Integer
r#) | Integer
r Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
0 -> Integer -> b
forall a. Num a => Integer -> a
fromInteger Integer
q
| Bool
otherwise -> Integer -> b
forall a. Num a => Integer -> a
fromInteger (Integer
q Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1)
{-# INLINABLE ceiling #-}
floor :: forall b. Integral b => Scientific -> b
floor = (Integer -> Int -> b) -> Scientific -> b
forall a. Num a => (Integer -> Int -> a) -> Scientific -> a
whenFloating ((Integer -> Int -> b) -> Scientific -> b)
-> (Integer -> Int -> b) -> Scientific -> b
forall a b. (a -> b) -> a -> b
$ \Integer
c Int
e ->
if Integer -> Int -> Bool
dangerouslySmall Integer
c Int
e
then if Integer
c Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0
then -b
1
else b
0
else Integer -> b
forall a. Num a => Integer -> a
fromInteger (Integer
c Integer -> Integer -> Integer
`divInteger` Int -> Integer
forall a. Num a => Int -> a
magnitude (-Int
e))
{-# INLINABLE floor #-}
dangerouslySmall :: Integer -> Int -> Bool
dangerouslySmall :: Integer -> Int -> Bool
dangerouslySmall Integer
c Int
e = Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< (-Int
limit) Bool -> Bool -> Bool
&& Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< (-Integer -> Int
integerLog10' (Integer -> Integer
forall a. Num a => a -> a
abs Integer
c)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
{-# INLINE dangerouslySmall #-}
limit :: Int
limit :: Int
limit = Int
maxExpt
positivize :: (Ord a, Num a, Num b) => (a -> b) -> (a -> b)
positivize :: forall a b. (Ord a, Num a, Num b) => (a -> b) -> a -> b
positivize a -> b
f a
x | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 = -(a -> b
f (-a
x))
| Bool
otherwise = a -> b
f a
x
{-# INLINE positivize #-}
whenFloating :: (Num a) => (Integer -> Int -> a) -> Scientific -> a
whenFloating :: forall a. Num a => (Integer -> Int -> a) -> Scientific -> a
whenFloating Integer -> Int -> a
f s :: Scientific
s@(Scientific Integer
c Int
e)
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Integer -> Int -> a
f Integer
c Int
e
| Bool
otherwise = Scientific -> a
forall a. Num a => Scientific -> a
toIntegral Scientific
s
{-# INLINE whenFloating #-}
toIntegral :: (Num a) => Scientific -> a
toIntegral :: forall a. Num a => Scientific -> a
toIntegral (Scientific Integer
c Int
e) = Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
c a -> a -> a
forall a. Num a => a -> a -> a
* Int -> a
forall a. Num a => Int -> a
magnitude Int
e
{-# INLINE toIntegral #-}
fromFloatDigits :: (RealFloat a) => a -> Scientific
fromFloatDigits :: forall a. RealFloat a => a -> Scientific
fromFloatDigits a
0 = Scientific
0
fromFloatDigits a
rf = (a -> Scientific) -> a -> Scientific
forall a b. (Ord a, Num a, Num b) => (a -> b) -> a -> b
positivize a -> Scientific
forall a. RealFloat a => a -> Scientific
fromPositiveRealFloat a
rf
where
fromPositiveRealFloat :: p -> Scientific
fromPositiveRealFloat p
r = [Int] -> Integer -> Int -> Scientific
go [Int]
digits Integer
0 Int
0
where
([Int]
digits, Int
e) = Integer -> p -> ([Int], Int)
forall a. RealFloat a => Integer -> a -> ([Int], Int)
Numeric.floatToDigits Integer
10 p
r
go :: [Int] -> Integer -> Int -> Scientific
go :: [Int] -> Integer -> Int -> Scientific
go [] !Integer
c !Int
n = Integer -> Int -> Scientific
Scientific Integer
c (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)
go (Int
d:[Int]
ds) !Integer
c !Int
n = [Int] -> Integer -> Int -> Scientific
go [Int]
ds (Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
10 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
d) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINABLE fromFloatDigits #-}
{-# SPECIALIZE fromFloatDigits :: Double -> Scientific #-}
{-# SPECIALIZE fromFloatDigits :: Float -> Scientific #-}
toRealFloat :: (RealFloat a) => Scientific -> a
toRealFloat :: forall a. RealFloat a => Scientific -> a
toRealFloat = (a -> a) -> (a -> a) -> Either a a -> a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> a
forall a. a -> a
id a -> a
forall a. a -> a
id (Either a a -> a) -> (Scientific -> Either a a) -> Scientific -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> Either a a
forall a. RealFloat a => Scientific -> Either a a
toBoundedRealFloat
{-# INLINABLE toRealFloat #-}
{-# INLINABLE toBoundedRealFloat #-}
{-# SPECIALIZE toRealFloat :: Scientific -> Double #-}
{-# SPECIALIZE toRealFloat :: Scientific -> Float #-}
{-# SPECIALIZE toBoundedRealFloat :: Scientific -> Either Double Double #-}
{-# SPECIALIZE toBoundedRealFloat :: Scientific -> Either Float Float #-}
toBoundedRealFloat :: forall a. (RealFloat a) => Scientific -> Either a a
toBoundedRealFloat :: forall a. RealFloat a => Scientific -> Either a a
toBoundedRealFloat s :: Scientific
s@(Scientific Integer
c Int
e)
| Integer
c Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = a -> Either a a
forall a b. b -> Either a b
Right a
0
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
limit = if Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
hiLimit then a -> Either a a
forall a b. a -> Either a b
Left (a -> Either a a) -> a -> Either a a
forall a b. (a -> b) -> a -> b
$ a -> a
forall a. Num a => a -> a
sign (a
1a -> a -> a
forall a. Fractional a => a -> a -> a
/a
0)
else a -> Either a a
forall a b. b -> Either a b
Right (a -> Either a a) -> a -> Either a a
forall a b. (a -> b) -> a -> b
$ Rational -> a
forall a. Fractional a => Rational -> a
fromRational ((Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Num a => Int -> a
magnitude Int
e) Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
1)
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< -Int
limit = if Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
loLimit Bool -> Bool -> Bool
&& Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
loLimit then a -> Either a a
forall a b. a -> Either a b
Left (a -> Either a a) -> a -> Either a a
forall a b. (a -> b) -> a -> b
$ a -> a
forall a. Num a => a -> a
sign a
0
else a -> Either a a
forall a b. b -> Either a b
Right (a -> Either a a) -> a -> Either a a
forall a b. (a -> b) -> a -> b
$ Rational -> a
forall a. Fractional a => Rational -> a
fromRational (Integer
c Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Int -> Integer
forall a. Num a => Int -> a
magnitude (-Int
e))
| Bool
otherwise = a -> Either a a
forall a b. b -> Either a b
Right (a -> Either a a) -> a -> Either a a
forall a b. (a -> b) -> a -> b
$ Rational -> a
forall a. Fractional a => Rational -> a
fromRational (Scientific -> Rational
forall a. Real a => a -> Rational
toRational Scientific
s)
where
hiLimit, loLimit :: Int
hiLimit :: Int
hiLimit = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
hi Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
log10Radix)
loLimit :: Int
loLimit = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
lo Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
log10Radix) Int -> Int -> Int
forall a. Num a => a -> a -> a
-
Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
digits Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
log10Radix)
log10Radix :: Double
log10Radix :: Double
log10Radix = Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase Double
10 (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
radix
radix :: Integer
radix = a -> Integer
forall a. RealFloat a => a -> Integer
floatRadix (a
forall a. HasCallStack => a
undefined :: a)
digits :: Int
digits = a -> Int
forall a. RealFloat a => a -> Int
floatDigits (a
forall a. HasCallStack => a
undefined :: a)
(Int
lo, Int
hi) = a -> (Int, Int)
forall a. RealFloat a => a -> (Int, Int)
floatRange (a
forall a. HasCallStack => a
undefined :: a)
d :: Int
d = Integer -> Int
integerLog10' (Integer -> Integer
forall a. Num a => a -> a
abs Integer
c)
sign :: a -> a
sign a
x | Integer
c Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = -a
x
| Bool
otherwise = a
x
toBoundedInteger :: forall i. (Integral i, Bounded i) => Scientific -> Maybe i
toBoundedInteger :: forall i. (Integral i, Bounded i) => Scientific -> Maybe i
toBoundedInteger (Scientific -> Maybe Scientific
isInteger_ -> Just (Scientific Integer
c Int
e))
| Integer
c Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = Integer -> Maybe i
fromIntegerBounded Integer
0
| Int
e Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Integer -> Maybe i
fromIntegerBounded Integer
c
| Bool
dangerouslyBig = Maybe i
forall a. Maybe a
Nothing
| Bool
otherwise = Integer -> Maybe i
fromIntegerBounded Integer
n
where
l :: Int
l = Integer -> Int
integerLog10' (Integer -> Integer
forall a. Num a => a -> a
abs Integer
c) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
e
dangerouslyBig :: Bool
dangerouslyBig = Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Integer -> Int
integerLog10' (Integer -> Integer -> Integer
forall a. Ord a => a -> a -> a
max (Integer -> Integer
forall a. Num a => a -> a
abs Integer
iMinBound) (Integer -> Integer
forall a. Num a => a -> a
abs Integer
iMaxBound))
fromIntegerBounded :: Integer -> Maybe i
fromIntegerBounded :: Integer -> Maybe i
fromIntegerBounded Integer
i
| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
iMinBound Bool -> Bool -> Bool
|| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
iMaxBound = Maybe i
forall a. Maybe a
Nothing
| Bool
otherwise = i -> Maybe i
forall a. a -> Maybe a
Just (i -> Maybe i) -> i -> Maybe i
forall a b. (a -> b) -> a -> b
$ Integer -> i
forall a. Num a => Integer -> a
fromInteger Integer
i
iMinBound :: Integer
iMinBound = i -> Integer
forall a. Integral a => a -> Integer
toInteger (i
forall a. Bounded a => a
minBound :: i)
iMaxBound :: Integer
iMaxBound = i -> Integer
forall a. Integral a => a -> Integer
toInteger (i
forall a. Bounded a => a
maxBound :: i)
n :: Integer
n :: Integer
n = Integer
c Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Num a => Int -> a
magnitude Int
e
toBoundedInteger Scientific
_ = Maybe i
forall a. Maybe a
Nothing
{-# SPECIALIZE toBoundedInteger :: Scientific -> Maybe Int #-}
{-# SPECIALIZE toBoundedInteger :: Scientific -> Maybe Int8 #-}
{-# SPECIALIZE toBoundedInteger :: Scientific -> Maybe Int16 #-}
{-# SPECIALIZE toBoundedInteger :: Scientific -> Maybe Int32 #-}
{-# SPECIALIZE toBoundedInteger :: Scientific -> Maybe Int64 #-}
{-# SPECIALIZE toBoundedInteger :: Scientific -> Maybe Word #-}
{-# SPECIALIZE toBoundedInteger :: Scientific -> Maybe Word8 #-}
{-# SPECIALIZE toBoundedInteger :: Scientific -> Maybe Word16 #-}
{-# SPECIALIZE toBoundedInteger :: Scientific -> Maybe Word32 #-}
{-# SPECIALIZE toBoundedInteger :: Scientific -> Maybe Word64 #-}
floatingOrInteger :: (RealFloat r, Integral i) => Scientific -> Either r i
floatingOrInteger :: forall r i. (RealFloat r, Integral i) => Scientific -> Either r i
floatingOrInteger Scientific
s
| Just Scientific
s' <- Scientific -> Maybe Scientific
isInteger_ Scientific
s
= i -> Either r i
forall a b. b -> Either a b
Right (Scientific -> i
forall a. Num a => Scientific -> a
toIntegral Scientific
s')
| Bool
otherwise
= r -> Either r i
forall a b. a -> Either a b
Left (Scientific -> r
forall a. RealFloat a => Scientific -> a
toRealFloat Scientific
s)
isFloating :: Scientific -> Bool
isFloating :: Scientific -> Bool
isFloating = Bool -> Bool
not (Bool -> Bool) -> (Scientific -> Bool) -> Scientific -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> Bool
isInteger
isInteger :: Scientific -> Bool
isInteger :: Scientific -> Bool
isInteger = Maybe Scientific -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Scientific -> Bool)
-> (Scientific -> Maybe Scientific) -> Scientific -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> Maybe Scientific
isInteger_
isInteger_ :: Scientific -> Maybe Scientific
isInteger_ :: Scientific -> Maybe Scientific
isInteger_ s :: Scientific
s@(Scientific Integer
c Int
e)
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 = Scientific -> Maybe Scientific
forall a. a -> Maybe a
Just Scientific
s
| Integer
c Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = Scientific -> Maybe Scientific
forall a. a -> Maybe a
Just (Integer -> Int -> Scientific
Scientific Integer
c Int
0)
| Integer -> Int
integerLog10' (Integer -> Integer
forall a. Num a => a -> a
abs Integer
c) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int -> Int
forall a. Num a => a -> a
negate Int
e = Maybe Scientific
forall a. Maybe a
Nothing
| Integer
c Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0
, let (Integer
q, Integer
r) = Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
quotRem (Integer -> Integer
forall a. Num a => a -> a
negate Integer
c) (Int -> Integer
forall a. Num a => Int -> a
magnitude (Int -> Int
forall a. Num a => a -> a
negate Int
e))
= if Integer
r Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 then Scientific -> Maybe Scientific
forall a. a -> Maybe a
Just (Integer -> Int -> Scientific
Scientific (Integer -> Integer
forall a. Num a => a -> a
negate Integer
q) Int
0) else Maybe Scientific
forall a. Maybe a
Nothing
| Bool
otherwise
, let (Integer
q, Integer
r) = Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
quotRem Integer
c (Int -> Integer
forall a. Num a => Int -> a
magnitude (Int -> Int
forall a. Num a => a -> a
negate Int
e))
= if Integer
r Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 then Scientific -> Maybe Scientific
forall a. a -> Maybe a
Just (Integer -> Int -> Scientific
Scientific Integer
q Int
0) else Maybe Scientific
forall a. Maybe a
Nothing
instance Read Scientific where
readPrec :: ReadPrec Scientific
readPrec = ReadPrec Scientific -> ReadPrec Scientific
forall a. ReadPrec a -> ReadPrec a
Read.parens (ReadPrec Scientific -> ReadPrec Scientific)
-> ReadPrec Scientific -> ReadPrec Scientific
forall a b. (a -> b) -> a -> b
$ ReadP Scientific -> ReadPrec Scientific
forall a. ReadP a -> ReadPrec a
ReadPrec.lift (ReadP ()
ReadP.skipSpaces ReadP () -> ReadP Scientific -> ReadP Scientific
forall a b. ReadP a -> ReadP b -> ReadP b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ReadP Scientific
scientificP)
data SP = SP !Integer {-# UNPACK #-}!Int
scientificP :: ReadP Scientific
scientificP :: ReadP Scientific
scientificP = do
let positive :: ReadP Bool
positive = ((Char
'+' Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==) (Char -> Bool) -> ReadP Char -> ReadP Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Bool) -> ReadP Char
ReadP.satisfy Char -> Bool
isSign) ReadP Bool -> ReadP Bool -> ReadP Bool
forall a. ReadP a -> ReadP a -> ReadP a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Bool -> ReadP Bool
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
Bool
pos <- ReadP Bool
positive
let step :: Num a => a -> Int -> a
step :: forall a. Num a => a -> Int -> a
step a
a Int
digit = a
a a -> a -> a
forall a. Num a => a -> a -> a
* a
10 a -> a -> a
forall a. Num a => a -> a -> a
+ Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
digit
{-# INLINE step #-}
[Char]
ds <- (Char -> Bool) -> ReadP [Char]
ReadP.munch1 Char -> Bool
isDecimal
let n :: Integer
n = [Char] -> Integer
forall a. Read a => [Char] -> a
read [Char]
ds :: Integer
let s :: SP
s = Integer -> Int -> SP
SP Integer
n Int
0
fractional :: ReadP SP
fractional = (SP -> Int -> SP) -> SP -> ReadP SP
forall a. (a -> Int -> a) -> a -> ReadP a
foldDigits (\(SP Integer
a Int
e) Int
digit ->
Integer -> Int -> SP
SP (Integer -> Int -> Integer
forall a. Num a => a -> Int -> a
step Integer
a Int
digit) (Int
eInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)) SP
s
SP Integer
coeff Int
expnt <- ((Char -> Bool) -> ReadP Char
ReadP.satisfy (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.') ReadP Char -> ReadP SP -> ReadP SP
forall a b. ReadP a -> ReadP b -> ReadP b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ReadP SP
fractional)
ReadP SP -> ReadP SP -> ReadP SP
forall a. ReadP a -> ReadP a -> ReadP a
ReadP.<++ SP -> ReadP SP
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return SP
s
let signedCoeff :: Integer
signedCoeff | Bool
pos = Integer
coeff
| Bool
otherwise = (-Integer
coeff)
eP :: ReadP Int
eP = do Bool
posE <- ReadP Bool
positive
Int
e <- (Int -> Int -> Int) -> Int -> ReadP Int
forall a. (a -> Int -> a) -> a -> ReadP a
foldDigits Int -> Int -> Int
forall a. Num a => a -> Int -> a
step Int
0
if Bool
posE
then Int -> ReadP Int
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
e
else Int -> ReadP Int
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return (-Int
e)
((Char -> Bool) -> ReadP Char
ReadP.satisfy Char -> Bool
isE ReadP Char -> ReadP Scientific -> ReadP Scientific
forall a b. ReadP a -> ReadP b -> ReadP b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
((Integer -> Int -> Scientific
Scientific Integer
signedCoeff (Int -> Scientific) -> (Int -> Int) -> Int -> Scientific
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int
expnt Int -> Int -> Int
forall a. Num a => a -> a -> a
+)) (Int -> Scientific) -> ReadP Int -> ReadP Scientific
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadP Int
eP)) ReadP Scientific -> ReadP Scientific -> ReadP Scientific
forall a. ReadP a -> ReadP a -> ReadP a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus`
Scientific -> ReadP Scientific
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Int -> Scientific
Scientific Integer
signedCoeff Int
expnt)
foldDigits :: (a -> Int -> a) -> a -> ReadP a
foldDigits :: forall a. (a -> Int -> a) -> a -> ReadP a
foldDigits a -> Int -> a
f a
z = do
Char
c <- (Char -> Bool) -> ReadP Char
ReadP.satisfy Char -> Bool
isDecimal
let digit :: Int
digit = Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
48
a :: a
a = a -> Int -> a
f a
z Int
digit
ReadP [Char]
ReadP.look ReadP [Char] -> ([Char] -> ReadP a) -> ReadP a
forall a b. ReadP a -> (a -> ReadP b) -> ReadP b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> [Char] -> ReadP a
go a
a
where
go :: a -> [Char] -> ReadP a
go !a
a [] = a -> ReadP a
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
go !a
a (Char
c:[Char]
cs)
| Char -> Bool
isDecimal Char
c = do
Char
_ <- ReadP Char
ReadP.get
let digit :: Int
digit = Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
48
a -> [Char] -> ReadP a
go (a -> Int -> a
f a
a Int
digit) [Char]
cs
| Bool
otherwise = a -> ReadP a
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
isDecimal :: Char -> Bool
isDecimal :: Char -> Bool
isDecimal Char
c = Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'9'
{-# INLINE isDecimal #-}
isSign :: Char -> Bool
isSign :: Char -> Bool
isSign Char
c = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'+'
{-# INLINE isSign #-}
isE :: Char -> Bool
isE :: Char -> Bool
isE Char
c = Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'e' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'E'
{-# INLINE isE #-}
instance Show Scientific where
showsPrec :: Int -> Scientific -> [Char] -> [Char]
showsPrec Int
d Scientific
s
| Scientific -> Integer
coefficient Scientific
s Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = Bool -> ([Char] -> [Char]) -> [Char] -> [Char]
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
prefixMinusPrec) (([Char] -> [Char]) -> [Char] -> [Char])
-> ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$
Char -> [Char] -> [Char]
showChar Char
'-' ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> [Char] -> [Char]
showPositive (-Scientific
s)
| Bool
otherwise = Scientific -> [Char] -> [Char]
showPositive Scientific
s
where
prefixMinusPrec :: Int
prefixMinusPrec :: Int
prefixMinusPrec = Int
6
showPositive :: Scientific -> ShowS
showPositive :: Scientific -> [Char] -> [Char]
showPositive = [Char] -> [Char] -> [Char]
showString ([Char] -> [Char] -> [Char])
-> (Scientific -> [Char]) -> Scientific -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Int], Int) -> [Char]
fmtAsGeneric (([Int], Int) -> [Char])
-> (Scientific -> ([Int], Int)) -> Scientific -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> ([Int], Int)
toDecimalDigits
fmtAsGeneric :: ([Int], Int) -> String
fmtAsGeneric :: ([Int], Int) -> [Char]
fmtAsGeneric x :: ([Int], Int)
x@([Int]
_is, Int
e)
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
7 = ([Int], Int) -> [Char]
fmtAsExponent ([Int], Int)
x
| Bool
otherwise = ([Int], Int) -> [Char]
fmtAsFixed ([Int], Int)
x
fmtAsExponent :: ([Int], Int) -> String
fmtAsExponent :: ([Int], Int) -> [Char]
fmtAsExponent ([Int]
is, Int
e) =
case [Char]
ds of
[Char]
"0" -> [Char]
"0.0e0"
[Char
d] -> Char
d Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Char
'.' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:Char
'0' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Char
'e' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char]
show_e'
(Char
d:[Char]
ds') -> Char
d Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Char
'.' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char]
ds' [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ (Char
'e' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char]
show_e')
[] -> [Char] -> [Char]
forall a. HasCallStack => [Char] -> a
error [Char]
"formatScientific/doFmt/FFExponent: []"
where
show_e' :: [Char]
show_e' = Int -> [Char]
forall a. Show a => a -> [Char]
show (Int
eInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
ds :: [Char]
ds = (Int -> Char) -> [Int] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
intToDigit [Int]
is
fmtAsFixed :: ([Int], Int) -> String
fmtAsFixed :: ([Int], Int) -> [Char]
fmtAsFixed ([Int]
is, Int
e)
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = Char
'0'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:Char
'.'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:(Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate (-Int
e) Char
'0' [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
ds)
| Bool
otherwise =
let
f :: t -> [Char] -> [Char] -> [Char]
f t
0 [Char]
s [Char]
rs = [Char] -> [Char]
mk0 ([Char] -> [Char]
forall a. [a] -> [a]
reverse [Char]
s) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Char
'.'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char] -> [Char]
mk0 [Char]
rs
f t
n [Char]
s [Char]
"" = t -> [Char] -> [Char] -> [Char]
f (t
nt -> t -> t
forall a. Num a => a -> a -> a
-t
1) (Char
'0'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
s) [Char]
""
f t
n [Char]
s (Char
r:[Char]
rs) = t -> [Char] -> [Char] -> [Char]
f (t
nt -> t -> t
forall a. Num a => a -> a -> a
-t
1) (Char
rChar -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
s) [Char]
rs
in
Int -> [Char] -> [Char] -> [Char]
forall {t}. (Eq t, Num t) => t -> [Char] -> [Char] -> [Char]
f Int
e [Char]
"" [Char]
ds
where
mk0 :: [Char] -> [Char]
mk0 [Char]
"" = [Char]
"0"
mk0 [Char]
ls = [Char]
ls
ds :: [Char]
ds = (Int -> Char) -> [Int] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
intToDigit [Int]
is
formatScientific :: FPFormat
-> Maybe Int
-> Scientific
-> String
formatScientific :: FPFormat -> Maybe Int -> Scientific -> [Char]
formatScientific FPFormat
format Maybe Int
mbDecs Scientific
s
| Scientific -> Integer
coefficient Scientific
s Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = Char
'-'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:Scientific -> [Char]
formatPositiveScientific (-Scientific
s)
| Bool
otherwise = Scientific -> [Char]
formatPositiveScientific Scientific
s
where
formatPositiveScientific :: Scientific -> String
formatPositiveScientific :: Scientific -> [Char]
formatPositiveScientific Scientific
s' = case FPFormat
format of
FPFormat
Generic -> ([Int], Int) -> [Char]
fmtAsGeneric (([Int], Int) -> [Char]) -> ([Int], Int) -> [Char]
forall a b. (a -> b) -> a -> b
$ Scientific -> ([Int], Int)
toDecimalDigits Scientific
s'
FPFormat
Exponent -> ([Int], Int) -> [Char]
fmtAsExponentMbDecs (([Int], Int) -> [Char]) -> ([Int], Int) -> [Char]
forall a b. (a -> b) -> a -> b
$ Scientific -> ([Int], Int)
toDecimalDigits Scientific
s'
FPFormat
Fixed -> ([Int], Int) -> [Char]
fmtAsFixedMbDecs (([Int], Int) -> [Char]) -> ([Int], Int) -> [Char]
forall a b. (a -> b) -> a -> b
$ Scientific -> ([Int], Int)
toDecimalDigits Scientific
s'
fmtAsGeneric :: ([Int], Int) -> String
fmtAsGeneric :: ([Int], Int) -> [Char]
fmtAsGeneric x :: ([Int], Int)
x@([Int]
_is, Int
e)
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
7 = ([Int], Int) -> [Char]
fmtAsExponentMbDecs ([Int], Int)
x
| Bool
otherwise = ([Int], Int) -> [Char]
fmtAsFixedMbDecs ([Int], Int)
x
fmtAsExponentMbDecs :: ([Int], Int) -> String
fmtAsExponentMbDecs :: ([Int], Int) -> [Char]
fmtAsExponentMbDecs ([Int], Int)
x = case Maybe Int
mbDecs of
Maybe Int
Nothing -> ([Int], Int) -> [Char]
fmtAsExponent ([Int], Int)
x
Just Int
dec -> Int -> ([Int], Int) -> [Char]
fmtAsExponentDecs Int
dec ([Int], Int)
x
fmtAsFixedMbDecs :: ([Int], Int) -> String
fmtAsFixedMbDecs :: ([Int], Int) -> [Char]
fmtAsFixedMbDecs ([Int], Int)
x = case Maybe Int
mbDecs of
Maybe Int
Nothing -> ([Int], Int) -> [Char]
fmtAsFixed ([Int], Int)
x
Just Int
dec -> Int -> ([Int], Int) -> [Char]
fmtAsFixedDecs Int
dec ([Int], Int)
x
fmtAsExponentDecs :: Int -> ([Int], Int) -> String
fmtAsExponentDecs :: Int -> ([Int], Int) -> [Char]
fmtAsExponentDecs Int
dec ([Int]
is, Int
e) =
let dec' :: Int
dec' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
dec Int
1 in
case [Int]
is of
[Int
0] -> Char
'0' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:Char
'.' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Int -> [Char] -> [Char]
forall a. Int -> [a] -> [a]
take Int
dec' (Char -> [Char]
forall a. a -> [a]
repeat Char
'0') [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"e0"
[Int]
_ ->
let (Int
ei,[Int]
is') = Int -> [Int] -> (Int, [Int])
roundTo (Int
dec'Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) [Int]
is
in case (Int -> Char) -> [Int] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
intToDigit (if Int
ei Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then [Int] -> [Int]
forall a. HasCallStack => [a] -> [a]
init [Int]
is' else [Int]
is') of
[] -> [Char]
""
Char
d:[Char]
ds' -> Char
dChar -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:Char
'.'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
ds' [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Char
'e'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:Int -> [Char]
forall a. Show a => a -> [Char]
show (Int
eInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
ei)
fmtAsFixedDecs :: Int -> ([Int], Int) -> String
fmtAsFixedDecs :: Int -> ([Int], Int) -> [Char]
fmtAsFixedDecs Int
dec ([Int]
is, Int
e) =
let dec' :: Int
dec' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
dec Int
0 in
if Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then
let
(Int
ei,[Int]
is') = Int -> [Int] -> (Int, [Int])
roundTo (Int
dec' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
e) [Int]
is
([Char]
ls,[Char]
rs) = Int -> [Char] -> ([Char], [Char])
forall a. Int -> [a] -> ([a], [a])
splitAt (Int
eInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
ei) ((Int -> Char) -> [Int] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
intToDigit [Int]
is')
in
[Char] -> [Char]
mk0 [Char]
ls [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ (if [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Char]
rs then [Char]
"" else Char
'.'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
rs)
else
let (Int
ei,[Int]
is') = Int -> [Int] -> (Int, [Int])
roundTo Int
dec' (Int -> Int -> [Int]
forall a. Int -> a -> [a]
replicate (-Int
e) Int
0 [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int]
is)
in case (Int -> Char) -> [Int] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
intToDigit (if Int
ei Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then [Int]
is' else Int
0Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:[Int]
is') of
[] -> [Char]
""
Char
d:[Char]
ds' -> Char
d Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: (if [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Char]
ds' then [Char]
"" else Char
'.'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
ds')
where
mk0 :: [Char] -> [Char]
mk0 [Char]
ls = case [Char]
ls of { [Char]
"" -> [Char]
"0" ; [Char]
_ -> [Char]
ls}
toDecimalDigits :: Scientific -> ([Int], Int)
toDecimalDigits :: Scientific -> ([Int], Int)
toDecimalDigits (Scientific Integer
0 Int
_) = ([Int
0], Int
0)
toDecimalDigits (Scientific Integer
c' Int
e') =
case Integer -> Int -> Scientific
normalizePositive Integer
c' Int
e' of
Scientific Integer
c Int
e -> ([Int]
ds, [Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
ds Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
e)
where
ds :: [Int]
ds = (Char -> Int) -> [Char] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (\Char
d -> Char -> Int
ord Char
d Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
ord Char
'0') (Integer -> [Char]
forall a. Show a => a -> [Char]
show Integer
c)
normalize :: Scientific -> Scientific
normalize :: Scientific -> Scientific
normalize (Scientific Integer
c Int
e) = case Integer -> Integer -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Integer
c Integer
0 of
Ordering
GT -> Integer -> Int -> Scientific
normalizePositive Integer
c Int
e
Ordering
LT -> -(Integer -> Int -> Scientific
normalizePositive (-Integer
c) Int
e)
Ordering
EQ -> Integer -> Int -> Scientific
Scientific Integer
0 Int
0
normalizePositive :: Integer -> Int -> Scientific
normalizePositive :: Integer -> Int -> Scientific
normalizePositive !Integer
c !Int
e = case Integer -> Integer -> (Integer, Int)
stripPowers Integer
c Integer
10 of
(Integer
c', Int
k) -> Integer -> Int -> Scientific
Scientific Integer
c' (Int
eInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
k)
stripPowers :: Integer -> Integer -> (Integer, Int)
stripPowers :: Integer -> Integer -> (Integer, Int)
stripPowers !Integer
c !Integer
p
| Integer
r Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0
= (Integer
c, Int
0)
| let (Integer
c', Int
k) = Integer -> Integer -> (Integer, Int)
stripPowers Integer
q (Integer
pInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
p)
, let (Integer
q', Integer
r') = Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
quotRem Integer
c' Integer
p
= if Integer
r' Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 then (Integer
q', Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) else (Integer
c', Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
where
(Integer
q, Integer
r) = Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
quotRem Integer
c Integer
p