#include "thyme.h"
module Data.Thyme.Internal.Micro where
import Prelude
import Control.DeepSeq
import Data.AdditiveGroup
import Data.Basis
import Data.Data
import Data.Int
import Data.Ix
import Data.Ratio
import Data.Vector.Generic (Vector)
import Data.Vector.Generic.Mutable (MVector)
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import Data.VectorSpace
import GHC.Generics (Generic)
import System.Random
import Test.QuickCheck
#if !SHOW_INTERNAL
import Control.Monad
import Data.Char
import Data.Thyme.Format.Internal
import Numeric
import Text.ParserCombinators.ReadPrec
import Text.ParserCombinators.ReadP
import Text.Read
#endif
newtype Micro = Micro Int64 deriving (INSTANCES_MICRO)
#if SHOW_INTERNAL
deriving instance Show Micro
deriving instance Read Micro
#else
instance Show Micro where
showsPrec _ (Micro a) = sign . shows si . frac where
sign = if a < 0 then (:) '-' else id
(si, su) = abs a `divMod` 1000000
frac = if su == 0 then id else (:) '.' . fills06 su . drops0 su
instance Read Micro where
readPrec = lift $ do
sign <- (char '-' >> return negate) `mplus` return id
s <- readS_to_P readDec
us <- (`mplus` return 0) $ do
_ <- char '.'
[(us10, "")] <- (readDec . take 7 . (++ "000000"))
`fmap` munch1 isDigit
return (div (us10 + 5) 10)
return . Micro . sign $ s * 1000000 + us
#endif
microQuotRem, microDivMod :: Micro -> Micro -> (Int64, Micro)
microQuotRem (Micro a) (Micro b) = (n, Micro f) where (n, f) = quotRem a b
microDivMod (Micro a) (Micro b) = (n, Micro f) where (n, f) = divMod a b
instance AdditiveGroup Micro where
zeroV = Micro 0
(^+^) = \ (Micro a) (Micro b) -> Micro (a + b)
negateV = \ (Micro a) -> Micro (negate a)
instance VectorSpace Micro where
type Scalar Micro = Rational
s *^ Micro a = Micro . fromInteger $
case compare (2 * abs r) (denominator s) of
LT -> n
EQ -> if even n then n else m
GT -> m
where
(n, r) = quotRem (toInteger a * numerator s) (denominator s)
m = if r < 0 then n 1 else n + 1
instance HasBasis Micro where
type Basis Micro = ()
basisValue = \ _ -> Micro 1000000
decompose = \ (Micro a) -> [((), fromIntegral a % 1000000)]
decompose' = \ (Micro a) _ -> fromIntegral a % 1000000