#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
#if __GLASGOW_HASKELL__ == 704
import qualified Data.Vector.Generic
import qualified Data.Vector.Generic.Mutable
#endif
import Data.Vector.Unboxed.Deriving
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)
derivingUnbox "Micro" [t| Micro -> Int64 |]
[| \ (Micro a) -> a |] [| 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